
package com.rt.schedulenew.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.rt.schedulebase.core.config.MQConfig;
import com.rt.schedulebase.core.config.XRayMQConfig;
import com.rt.schedulebase.dto.*;
import com.rt.schedulebase.dto.terminal.QueryScheduledApplyDto;
import com.rt.schedulebase.entity.*;
import com.rt.schedulebase.mapper.*;
import com.rt.schedulenew.api.*;
import com.rt.schedulenew.dto.SignScheduleDto;
import com.rt.schedulenew.task.GetScheduleDateTask;
import com.rt.schedulenew.utils.base.BigDecimalUtil;
import com.rt.schedulenew.utils.base.CommonUtil;
import com.rt.schedulenew.utils.base.ConstantsUtil;
import com.rt.schedulenew.utils.global.JsonResult;
import com.rt.schedulenew.utils.global.JsonResultUtil;
import com.rt.schedulenew.utils.global.PageVO;
import com.rt.schedulenew.utils.pkgenerator.PKGeneratorSingle;
import com.rt.schedulenew.utils.util.DateUtil;
import com.rt.schedulenew.utils.util.EncoderUtil;
import com.rt.schedulenew.utils.util.JsonUtil;
import com.rt.schedulenew.utils.util.QrCodeUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Service
public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply> implements IExamApplyService {
    private Logger logger = LoggerFactory.getLogger(ExamApplyServiceImpl.class);

    // @Autowired
    // private ExamApplyMapper_Back baseMapper;
    @Autowired
    private ExamApplyItemMapper examApplyItemMapper;
    @Autowired
    private ExamScheduleMapper examScheduleMapper;
    @Autowired
    private ExamScheduleItemMapper examScheduleItemMapper;
    @Autowired
    private ExamReferMapper examReferMapper;
    @Autowired
    private IExamReferService examReferService;
    @Autowired
    private IExamReferItemService examReferItemService;
    @Autowired
    private DictExamQueueMapper dictExamQueueMapper;
    @Autowired
    private IConfigService configServiceImpl;
    @Autowired
    private ICommonService commonServiceImpl;
    @Autowired
    private IDictExamClassService dictExamClassService;
    @Autowired
    private IDictPrintPatternService printPatternService;
    @Autowired
    private RuleEngineServiceImpl ruleEngineServiceImpl;
    @Autowired
    private IDictDeptService dictDeptService;
    @Autowired
    private ExamApplyItemServiceImpl examApplyItemServiceImpl;
    @Autowired
    DataSourceTransactionManager transactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;
    @Autowired
    private ExamScheduleApmMapper examScheduleApmMapper;
    @Autowired
    private IDictExamItemService dictExamItemService;
    @Autowired
    private IExamApplyPatientService examApplyPatientService;
    @Autowired
    private IExamApplyService examApplyService;
    @Autowired
    private IExamScheduleApmService examScheduleApmService;
    @Autowired
    private IDictScheduleApmService dictScheduleApmService;
    @Autowired
    private IDictExamQueueService dictExamQueueService;
    @Autowired
    private IExamScheduleService examScheduleService;
    @Autowired
    private ExamScheduleItemServiceImpl examScheduleItemServiceImpl;
    @Autowired
    private IExamPatientLockService examPatientLockService;
    @Autowired
    private IExamPatientService examPatientService;
    @Autowired
    private IExamApplyPatientIdService idService;
    @Autowired
    private IScheduleSignService scheduleSignService;
    @Autowired
    private IExamSmsNoticeService examSmsNoticeService;
    @Autowired
    private DictItemGroupMapper dictItemGroupMapper;
    @Autowired
    private IDictSerialService dictSerialService;
    @Autowired
    private IDeptNoticeService deptNoticeService;
    @Autowired
    private IExamScheduleItemService scheduleItemService;

    @Autowired
    private XRayService xRayService;

    @Autowired
    private XRayMQConfig xRayMQConfig;

    @Resource
    MQConfig mqConfig;

    @Autowired
    private DictExamItemMapper dictExamItemMapper;

    @Override
    public ExamApply getExamApply(String applyNo, String terminalType) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("applyNo", applyNo);
        map.put("terminalType", terminalType);
        return baseMapper.getExamApply(map);
    }

    /**
     * 获取申请日期列表
     *
     * @param dto
     * @return
     */
    @Override
    public JsonResult getDateList(ExamApplyDto dto) {
        ExamApplyDto ea = new ExamApplyDto();
        String isCompliance = commonServiceImpl.mergeRuleForScheduleJudge(ea, dto);
        if (StringUtils.isNotBlank(isCompliance)) {
            return JsonResultUtil.failure(isCompliance);
        }
        JsonResult jsonResult = checkScheduleItemConflict(ea);
        if (Objects.nonNull(jsonResult)) {
            return jsonResult;
        }
        dto.setPerformDept(ea.getPerformDept());
        dto.setExamClass(ea.getExamClass());

        // 获取检查项目的队列
        List<DictExamQueueDto> lsQueue = commonServiceImpl.getQueueList(dto);
        if (CollectionUtils.isEmpty(lsQueue)) {
            String queueNameStr = (dto.getQueueName() != null) ? dto.getQueueName() : "";
            String strReturn = "由于系统未设置" + ea.getExamClass() + "检查类别" + queueNameStr
                    + "的可预约队列，您的检查申请暂时不能预约，如有疑问请到护士站咨询！";
            // String reminder =
            // configServiceImpl.customReminder(ConstantsUtil.ConfigName.NO_QUERY_EXAM_APPLY_REMINDER.key,
            // "", ea.getExamClass());
            // if (StringUtils.isNotBlank(reminder)) {
            // strReturn = reminder;
            // }
            return JsonResultUtil.failure(strReturn);
        }
        if (ea.getBeginDays() != null && ea.getBeginDays() > 0) {
            for (DictExamQueue queue : lsQueue) {
                int expireDays = (queue.getExpireDays() == null) ? 0 : queue.getExpireDays();
                if (queue.getExpireDays() == null || ea.getBeginDays() < expireDays) {
                    queue.setExpireDays(ea.getBeginDays());
                }
            }
        }
        String isSchedule = commonServiceImpl.isScheduleByFlags(ea.getItems(), dto.getTerminalType(),
                ea.getChargeType());
        if (StringUtils.isNotBlank(isSchedule)) {
            return JsonResultUtil.failure(isSchedule);
        }
        // 孕周期限制
        List<ExamApplyItemDto> gestationalItems = new ArrayList<>();
        if (StringUtils.isBlank(dto.getIsGreenChannel()) && ea.getSex() != null
                && ea.getSex().contains(ConstantsUtil.Gender.WOMAN.getValue())) {
            gestationalItems = commonServiceImpl.getGestationalItems(ea.getItems());
            if (CollectionUtils.isNotEmpty(gestationalItems) && StringUtils.isBlank(ea.getLastMensesDate())) {
                if (StringUtils.isNotBlank(ea.getSickId())) {
                    ea.setLastMensesDate(commonServiceImpl.getLastMensesDate(ea.getSickId()));
                }
                if (StringUtils.isBlank(ea.getLastMensesDate())) {
                    return JsonResultUtil.failure("该检查申请需要填写末次月经日期");
                }
            }
        }
        List<String> limitScheduleDate = configServiceImpl.limitScheduleDay(dto.getClassAttr(), ea.getApplyNo(), null);
        ea.setLimitScheduleDate(limitScheduleDate);
        ea.setUserId(dto.getUserId());
        ea.setQueueName(dto.getQueueName());
        ea.setStaffName(dto.getStaffName());
        ea.setIsGreenChannel(dto.getIsGreenChannel());
        commonServiceImpl.getOrgansOrPower(ea);
        // 计算开始和结束时间 并且生成时间列表
        Map<String, String> map = commonServiceImpl.getApplyGestDate(ea.getLastMensesDate(), gestationalItems);
        boolean isGestDate = false;
        if (map != null) {
            List<String> dates = new ArrayList<>();
            String cdate = DateUtil.getCurrDateStr();
            for (String sdate = map.get("startDate"),
                 edate = map.get("endDate"); sdate.compareTo(edate) <= 0; sdate = DateUtil.addDays2(sdate, 1)) {
                boolean bool = sdate.compareTo(cdate) < 0;
                if (!bool) {
                    dates.add(sdate);
                }
            }
            ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("gestDate-pool-%d").build();
            ExecutorService executor = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
            List<Future<ExamApplyDto>> futures = new ArrayList<>();
            List<ExamApplyDto> lsExamApplyDto = new ArrayList<>();
            for (String date : dates) {
                GetScheduleDateTask task = new GetScheduleDateTask();
                task.setCommonServiceImpl(commonServiceImpl);
                task.setApply(ea);
                task.setDate(date);
                task.setQueues(lsQueue);
                Future<ExamApplyDto> future = executor.submit(task);
                futures.add(future);
            }
            executor.shutdown();
            try {
                for (Future<ExamApplyDto> future2 : futures) {
                    if (future2 != null && future2.get() != null) {
                        if ("1".equals(future2.get().getEnabled())) {
                            isGestDate = true;
                        }
                        lsExamApplyDto.add(future2.get());
                    }
                }
            } catch (InterruptedException | ExecutionException ex3) {
                logger.error("gestDate-pool:" + ex3.getMessage(), ex3);
                throw new RuntimeException();
            }
            if (isGestDate) {
                lsExamApplyDto.removeIf(ead -> ead.getDate().compareTo(dto.getStartDate()) < 0
                        || ead.getDate().compareTo(dto.getEndDate()) > 0);
                return JsonResultUtil.success(lsExamApplyDto);
            }
        }
        List<String> dates = new ArrayList<>();
        String cdate = DateUtil.getCurrDateStr();
        for (String sdate = dto.getStartDate(), edate = dto.getEndDate();
             sdate.compareTo(edate) <= 0;
             sdate = DateUtil.addDays2(sdate, 1)) {

            boolean bool = sdate.compareTo(cdate) < 0;
            boolean bool2 = CollectionUtils.isNotEmpty(gestationalItems)
                    && !commonServiceImpl.isGestationalDate(sdate, ea.getLastMensesDate(), gestationalItems);
            if (!bool && !bool2) {
                dates.add(sdate);
            }
        }
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("scheduleDate-pool-%d").build();
        ExecutorService executor = new ThreadPoolExecutor(5, 200, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
        List<Future<ExamApplyDto>> futures = new ArrayList<>();
        List<ExamApplyDto> lsExamApplyDto = new ArrayList<>();
        for (String date : dates) {
            GetScheduleDateTask task = new GetScheduleDateTask();
            task.setCommonServiceImpl(commonServiceImpl);
            task.setApply(ea);
            task.setDate(date);
            task.setQueues(lsQueue);
            Future<ExamApplyDto> future = executor.submit(task);
            futures.add(future);
        }
        try {
            for (Future<ExamApplyDto> future : futures) {
                if (future != null && future.get() != null) {
                    lsExamApplyDto.add(future.get());
                }
            }
        } catch (InterruptedException | ExecutionException ex4) {
            logger.error("scheduleDate-pool:" + ex4.getMessage(), ex4);
            throw new RuntimeException();
        } finally {
            executor.shutdown();
        }
        return JsonResultUtil.success(lsExamApplyDto);
    }

    /**
     * 检测预约时间是否冲突
     *
     * @param ea
     * @return
     */
    private JsonResult checkScheduleItemConflict(ExamApplyDto ea) {
        // A列表项目比B列表项目至少优先或延后多少天多少小时
        List<ConfigDto.ItemBefore> list = JsonUtil.toList(
                configServiceImpl.getConfigByName(ConstantsUtil.ConfigName.ITEM_BEFORE.getKey()),
                ConfigDto.ItemBefore.class);
        if (CollectionUtils.isNotEmpty(ea.getItems()) && CollectionUtils.isNotEmpty(list)) {
            for (ConfigDto.ItemBefore itemBefore : list) {
                int maxDays = 0;
                int maxHours = 0;
                if (itemBefore.getBeforeDays() != null && itemBefore.getBeforeDays() > maxDays) {
                    maxDays = itemBefore.getBeforeDays();
                }
                if (itemBefore.getBeforeHours() != null && itemBefore.getBeforeHours() > maxHours) {
                    maxHours = itemBefore.getBeforeHours();
                }
                if (itemBefore.getAfterDays() != null && itemBefore.getAfterDays() > maxDays) {
                    maxDays = itemBefore.getAfterDays();
                }
                if (itemBefore.getAfterHours() != null && itemBefore.getAfterHours() > maxHours) {
                    maxHours = itemBefore.getAfterHours();
                }
                List<String> itemCodeA = new ArrayList<>();
                List<DictExamItem> examItemA = itemBefore.getExamItemA();
                if (examItemA != null) {
                    for (DictExamItem dei : examItemA) {
                        itemCodeA.add(dei.getExamClass() + "=" + dei.getItemCode());
                    }
                }
                List<String> itemCodeB = new ArrayList<>();
                List<DictExamItem> examItemB = itemBefore.getExamItemB();
                if (examItemB != null) {
                    for (DictExamItem dei2 : examItemB) {
                        itemCodeB.add(dei2.getExamClass() + "=" + dei2.getItemCode());
                    }
                }
                boolean boolA = false;
                boolean boolB = false;
                for (ExamApplyItemDto item : ea.getItems()) {
                    String itemCode = item.getExamClass() + "=" + item.getItemCode();
                    String itemCodeBlank = item.getExamClass() + "=空";
                    if (itemCodeA.contains(itemCode) || itemCodeA.contains(itemCodeBlank)) {
                        boolA = true;
                    }
                    if (itemCodeB.contains(itemCode) || itemCodeB.contains(itemCodeBlank)) {
                        boolB = true;
                    }
                }
                if (maxDays > 0 && boolA && boolB) {
                    return JsonResultUtil.failure("当前项目要求间隔" + maxDays + "天，无法预约！");
                }
                if (maxHours > 0 && boolA && boolB) {
                    return JsonResultUtil.failure("当前项目要求间隔" + maxHours + "小时，无法预约！");
                }
            }
        }
        return null;
    }

    @Override
    public JsonResult getApmList(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo()) && StringUtils.isBlank(dto.getItemCode())) {
            return JsonResultUtil.failure("未检测到您的检查申请单号，如有疑问请到护士站咨询！");
        }
        ExamApplyDto ea = new ExamApplyDto();
        // 校验申请单状态和合并申请单 如果报错直接返回
        String isCompliance = commonServiceImpl.mergeRuleForScheduleJudge(ea, dto);
        if (StringUtils.isNotBlank(isCompliance)) {
            return JsonResultUtil.failure(isCompliance);
        }
        if (StringUtils.isBlank(dto.getIsGreenChannel())) {
            // 判断是否填写了孕期
            if (ea.getSex().contains(ConstantsUtil.Gender.WOMAN.getKey())
                    && StringUtils.isBlank(ea.getLastMensesDate())) {
                // 有孕期限制的检查项目列表
                List<ExamApplyItemDto> gestationalItems = commonServiceImpl.getGestationalItems(ea.getItems());
                if (CollectionUtils.isNotEmpty(gestationalItems)) {
                    ea.setLastMensesDate(commonServiceImpl.getLastMensesDate(ea.getSickId()));
                    if (StringUtils.isBlank(ea.getLastMensesDate())) {
                        return JsonResultUtil.failure("该检查申请需要填写末次月经日期");
                    }
                }
            }
        }
        ea.setHospitalCode(dto.getHospitalCode());
        ea.setScheduleDate(dto.getScheduleDate());
        ea.setQueueName(dto.getQueueName());
        ea.setIsGreenChannel(dto.getIsGreenChannel());
        ea.setUserId(dto.getUserId());
        ea.setClassAttr(dto.getClassAttr());
        ea.setStaffName(dto.getStaffName());
        return commonServiceImpl.getScheduleApm(ea, dto.getScheduleDate());
    }

    /**
     * 锁定预约时段
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult setApm(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo()) && StringUtils.isBlank(dto.getItemCode())) {
            return JsonResultUtil.failure("未检测到您的检查申请单号，如有疑问请到护士站咨询！");
        }
        if (dto.getScheduleDate().compareTo(DateUtil.getCurrDateStr()) < 0) {
            return JsonResultUtil.failure("您选择的预约日期" + dto.getScheduleDate() + "已过，请重新选择！");
        }
        if (StringUtils.isNotBlank(dto.getMergeNo())
                && !CommonUtil.mergeNo2ApplyNos(dto.getMergeNo()).contains(dto.getApplyNo())) {
            return JsonResultUtil.failure("参数入参有误");
        }
        // 合并通道
        if (StringUtils.isNotBlank(dto.getIsMergeChannel())) {
            String[] mergeNoArr = dto.getMergeNo().split(",");
            if (mergeNoArr.length > 1) {
                for (String mergeNo : mergeNoArr) {
                    ExamApplyDto ea = new ExamApplyDto();
                    String applyno = mergeNo.substring(0, mergeNo.lastIndexOf("-"));
                    ea.setApplyNo(applyno);
                    ea.setMergeNo(mergeNo);
                    ea.setHospitalCode(dto.getHospitalCode());
                    ea.setTerminalType(dto.getTerminalType());
                    delApm(ea);
                }
            }
        }
        ExamApplyDto applyDto = new ExamApplyDto();
        dto.setSort("1");
        String isCompliance = commonServiceImpl.mergeRuleForScheduleJudge(applyDto, dto);
        applyDto.setItemCode(null);// 锁号不需要这个值
        if (StringUtils.isNotBlank(isCompliance)) {
            if ("01".equals(isCompliance)) {
                return JsonResultUtil.failure("2", "您已经预约该时段,请选择别的时段！");
            }
            return JsonResultUtil.failure(isCompliance);
        } else {
            if ("08".equals(applyDto.getScheduleStatus())) {
                return JsonResultUtil.failure("您已有预约时段,请取消预约后在锁定");
            }
            applyDto.setHospitalCode(dto.getHospitalCode());
            applyDto.setNewScheduleDate(dto.getScheduleDate());
            applyDto.setNewScheduleApm(dto.getScheduleApm());
            applyDto.setOldScheduleDate(applyDto.getScheduleDate());
            applyDto.setOldScheduleApm(applyDto.getScheduleApm());
            applyDto.setOldQueueName(applyDto.getQueueName());
            if (StringUtils.isNotBlank(dto.getMergeNo())) {
                applyDto.setMergeNo(dto.getMergeNo());
            }
            applyDto.setTerminalType(dto.getTerminalType());
            applyDto.setQueueName(dto.getQueueName());
            applyDto.setStartTime(dto.getStartTime());
            applyDto.setEndTime(dto.getEndTime());
            applyDto.setClassAttr(dto.getClassAttr());
            applyDto.setStaffName(dto.getStaffName());
            applyDto.setEarliestDate(dto.getEarliestDate());
            applyDto.setEarliestTime(dto.getEarliestTime());
            DictUsersDto obj = commonServiceImpl.dictUsers(dto);
            // 锁定时段
            JsonResult jsonResult = commonServiceImpl.setApm(applyDto, obj);
            return jsonResult;
        }
    }

    /**
     * 确认申请单预约时间
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult confirmApm(ExamApplyDto dto) throws Exception {
        if (StringUtils.isBlank(dto.getApplyNo())) {
            return JsonResultUtil.failure("申请单号不能为空");
        }
        dto.setApplyNo(dto.getApplyNo().split(",")[0]);
        if (StringUtils.isNotBlank(dto.getMergeNo())) {
            List<ExamScheduleItem> esList = examScheduleItemMapper.getScheduleForApplyNo(dto.getApplyNo());
            String[] mergeNoArr = dto.getMergeNo().split(",");
            String scheduleId = "";
            for (ExamScheduleItem es : esList) {
                String esMergeNo = es.getApplyNo() + "-" + es.getItemNo();
                if (esMergeNo.equals(mergeNoArr[0])) {
                    scheduleId = es.getScheduledId();
                }
            }
            for (ExamScheduleItem es : esList) {
                String esMergeNo = es.getApplyNo() + "-" + es.getItemNo();
                boolean isDel = true;
                for (String mergeNo : mergeNoArr) {
                    if (mergeNo.equals(esMergeNo) || !scheduleId.equals(es.getScheduledId())) {
                        isDel = false;
                        break;
                    }
                }
                if (isDel) {
                    ExamApplyDto ea = new ExamApplyDto();
                    ea.setApplyNo(es.getApplyNo());
                    ea.setMergeNo(esMergeNo);
                    ea.setHospitalCode(dto.getHospitalCode());
                    ea.setTerminalType(dto.getTerminalType());
                    delApm(ea);
                }
            }
        }
        ExamApplyDto examApplyInfo = commonServiceImpl.getExamApplyInfo(dto.getApplyNo(), dto.getTerminalType());
        if (examApplyInfo == null) {
            return JsonResultUtil.failure("没有预约申请或预约已被取消！");
        }
        if (StringUtils.isNotBlank(dto.getPhoneNumber())) {
            examApplyInfo.setPhoneNumber(dto.getPhoneNumber());
        }
        commonServiceImpl.getScheduleToExamApply(dto, examApplyInfo);
        if (StringUtils.isNotBlank(examApplyInfo.getExamStatus())
                || StringUtils.isBlank(examApplyInfo.getScheduledId())
                || "08".equals(examApplyInfo.getScheduleStatus())) {
            logger.info("检查状态{}", examApplyInfo.getExamStatus());
            logger.info("预约id{}", examApplyInfo.getScheduledId());
            logger.info("预约状态{}", examApplyInfo.getScheduleStatus());
            return JsonResultUtil.failure("您选择申请单预约状态已变,请刷新后重试!");
        }
        examApplyInfo.setClassAttr(dto.getClassAttr());
        List<ExamApplyItemDto> items = commonServiceImpl.getExamApplyItem(dto.getMergeNo(), examApplyInfo);
        if (items.size() == 0) {
            return JsonResultUtil.failure("您的检查项目单不存在，如有疑问请到护士站咨询！");
        }
        examApplyInfo.setItems(items);
        DictUsersDto obj = commonServiceImpl.dictUsers(dto);
        String chargeFlag = commonServiceImpl.getChargeFlag(examApplyInfo);
        examApplyInfo.setTerminalType(dto.getTerminalType());
        boolean isChargeFirst = configServiceImpl.getChargeFirstSchedule(examApplyInfo);
        if (isChargeFirst && "0".equals(chargeFlag)) {
            return JsonResultUtil.failure("您的检查申请未缴费，不能预约。如有疑问请到护士站咨询!");
        }
        if (isChargeFirst && "2".equals(chargeFlag)) {
            return JsonResultUtil.failure("您的检查申请已作废或已退费，不能预约。如有疑问请到护士站咨询!");
        }
        if (StringUtils.isBlank(examApplyInfo.getScheduleDate())
                || StringUtils.isBlank(examApplyInfo.getScheduleApm())) {
            return JsonResultUtil.failure("请选择您要预约的日期和时段！");
        }
        String queueClass = (examApplyInfo.getPriorityOrder() != null) ? examApplyInfo.getPriorityOrder() : "普通";
        ExamScheduleDto es2 = new ExamScheduleDto();
        es2.setScheduledId(examApplyInfo.getScheduledId());
        es2.setScheduleStatus("08");
        es2.setQueueClass(queueClass);
        es2.setScheduler(obj.getName());
        // 预约队列配置
        String queueNoClass = configServiceImpl.getConfigByName(ConstantsUtil.ConfigName.QUEUE_NO_CLASS.getKey());
        if (StringUtils.isNotBlank(queueNoClass) && queueNoClass.contains(examApplyInfo.getExamClass())) {
            Map<String, String> map = new HashMap<>();
            map.put("queueDate", examApplyInfo.getScheduleDate());
            map.put("queueName", examApplyInfo.getQueueName());
            map.put("queueApm", examApplyInfo.getScheduleApm());
            map.put("queueClass", examApplyInfo.getPriorityOrder());
            String queueNo = examScheduleMapper.getScheduleQueueNo(map);
            es2.setQueueNo(queueNo);
            examApplyInfo.setQueueNo(queueNo);
        }
        int i = examScheduleMapper.updateExamSchedule(es2);
        if (i == 0) {
            return JsonResultUtil.failure("没有可确定的预约！");
        }
        List<String> applyNos = CommonUtil.mergeNo2ApplyNos(dto.getMergeNo());
        if (applyNos.size() == 0) {
            applyNos.add(dto.getApplyNo());
        }
        dto.setApplyNos(applyNos);
        dto.setQueueName(examApplyInfo.getQueueName());
        JsonResult confirmFeeBeforeScheduleResult = commonServiceImpl.confirmFeeBeforeSchedule(examApplyInfo,
                ConstantsUtil.ActType.CONFIRM.getType(), obj);
        if (confirmFeeBeforeScheduleResult != null && !"0".equals(confirmFeeBeforeScheduleResult.getStatus())) {
            String scheduleStatusByConfirmFee = configServiceImpl
                    .getConfigByName(ConstantsUtil.ConfigName.SCHEDULE_STATUS_BY_CONFIRM_FEE.getKey());
            if (StringUtils.isNotBlank(scheduleStatusByConfirmFee) && "1".equals(scheduleStatusByConfirmFee)) {
                dto.setActDescription("确费失败,该申请单[" + dto.getMergeNo() + "]回退到未预约状态");
                delApm(dto);
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
            return JsonResultUtil.failure(confirmFeeBeforeScheduleResult.getMessage());
        }

        boolean isNotUpdateChargeFlagByConfirmFee = configServiceImpl
                .isOpenConfig(ConstantsUtil.ConfigName.IS_NOT_UPDATE_CHARGE_FLAG_BY_CONFIRM_FEE.getKey());
        if (confirmFeeBeforeScheduleResult != null && "0".equals(confirmFeeBeforeScheduleResult.getStatus())
                && !isNotUpdateChargeFlagByConfirmFee) {
            ExamApplyDto up = new ExamApplyDto();
            up.setApplyNos(applyNos);
            up.setChargeFlag("1");
            baseMapper.updateExamApply(up);
        }
        // 是否是先排队-签到
        Boolean isGetQueueNoFirst = configServiceImpl.isGetQueueNoFirst(examApplyInfo.getPatientSource(),
                examApplyInfo.getQueueName());
        if (isGetQueueNoFirst) {
            ExamApplyDto examApplyDto = new ExamApplyDto();
            examApplyDto.setApplyNos(applyNos);
            String actType = ConstantsUtil.ActType.CONFIRM.getType();
            examApplyDto.setActType(actType);
            examApplyDto.setExamClass(examApplyInfo.getExamClass());
            examApplyDto.setScheduledId(examApplyInfo.getScheduledId());
            examApplyDto.setMergeNo(examApplyInfo.getMergeNo());
            examApplyDto.setApplyNo(dto.getApplyNo());
            boolean bool = configServiceImpl.isScheduleSync(examApplyDto, actType,
                    ConstantsUtil.ScheduleStatus.EIGHT.getStatus());
            if (!bool) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return JsonResultUtil.failure("预约失败,请联系工作人员");
            }
            dto.setSignInLimit("1");
            // 签到
            JsonResult jsonResult = signinSchedule(dto);
            if (jsonResult.getStatus().equals("1")) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return JsonResultUtil.failure("预约成功后报到，失败原因：" + jsonResult.getMessage());
            }
        }
        examApplyInfo.setTerminalType(dto.getTerminalType());
        examApplyInfo.setActType(ConstantsUtil.ActType.CONFIRM.getType());
        examApplyInfo.setHospitalCode(dto.getHospitalCode());
        commonServiceImpl.addExamScheduleAct(examApplyInfo, obj);
        if (ConstantsUtil.TerminalType.SELF.getType().equals(dto.getTerminalType())
                || ConstantsUtil.TerminalType.MOBILE.getType().equals(dto.getTerminalType())) {
            ExamApplyItemDto it = new ExamApplyItemDto();
            it.setApplyNos(applyNos);
            it.setScheCancel(1);
            examApplyItemMapper.updateItem(it);
        }
        List<String> notices = new ArrayList<>();
        List<String> itemNameList = new ArrayList<>();
        for (ExamApplyItemDto item : items) {
            if (StringUtils.isNotBlank(item.getNotice())) {
                notices.add(item.getNotice());
                itemNameList.add(item.getItemName());
            }
        }
        DictScheduleApm dsa = dictScheduleApmService.selectOneByApmCode(examApplyInfo.getApmCode());
        String endTime = DateUtil.addSecond(dsa.getTimeEnd(), 1);
        endTime = endTime.substring(0, dsa.getTimeEnd().length() - 3);
        String startTime = dsa.getTimeStart().substring(0, dsa.getTimeStart().length() - 3);
        List<Map<String, String>> convertSms = CommonUtil.convertSms(notices, examApplyInfo.getScheduleDate(),
                startTime, endTime);
        if (CollectionUtils.isNotEmpty(convertSms)) {
            commonServiceImpl.addSmsByItemNotice(examApplyInfo, convertSms, dto);
        }
        commonServiceImpl.addExamSmsNotice(examApplyInfo, ConstantsUtil.SmsType.SCHEDULE.getType(), dto);
        ExamApplyDto examApplyDto = new ExamApplyDto();
        BeanUtils.copyProperties(examApplyInfo, examApplyDto);
        examApplyDto.setScheduledId(examApplyInfo.getScheduledId());
        examApplyDto.setApplyNo(dto.getApplyNo());
        examApplyDto.setChargeFlag(chargeFlag);
        examApplyDto.setScheduleStatus("2");
        examApplyDto.setUserId(obj.getUserId());
        examApplyDto.setUserName(obj.getName());
        DictScheduleApmDto scheduleApm = commonServiceImpl.getTimeEarliest(examApplyInfo.getApmCode());
        String timeEarliest = scheduleApm.getTimeEarliest();
        String timeSignin = scheduleApm.getTimeSignin();
        examApplyDto.setMergeNo(dto.getMergeNo());
        examApplyDto.setTimeEarliest(timeEarliest);
        examApplyDto.setTimeSignin(timeSignin);
        examApplyDto.setTerminalType(dto.getTerminalType());
        if (isGetQueueNoFirst) {
            examApplyDto.setIsPrint(configServiceImpl.isPrint4Sign(examApplyInfo) ? "1" : "0");
            examApplyDto.setIsRemindPrint(configServiceImpl.isRemindPrint4Sign(examApplyInfo) ? "1" : "0");
            String actType2 = ConstantsUtil.ActType.SIGN.getType();
            examApplyDto.setActType(actType2);
        } else {
            examApplyDto.setIsPrint(configServiceImpl.isPrint4Schedule(examApplyInfo) ? "1" : "0");
            examApplyDto.setIsRemindPrint(configServiceImpl.isRemindPrint4Schedule(examApplyInfo) ? "1" : "0");
            // 预约当日是否自动报到
            String isSign = configServiceImpl.isScheduleTodayBySign(examApplyDto, scheduleApm) ? "1" : "0";
            examApplyDto.setIsSign(isSign);

            String confirmType = ConstantsUtil.ActType.CONFIRM.getType();
            examApplyDto.setActType(confirmType);
            examApplyDto.setIsPrintCode(configServiceImpl.isPrintCode4Schedule(examApplyInfo) ? "1" : "0");
        }
        DictExamQueueDto deq = new DictExamQueueDto();
        deq.setQueueName(examApplyInfo.getQueueName());
        List<DictExamQueue> list = dictExamQueueService.selectList(deq);
        if (CollectionUtils.isNotEmpty(list)) {
            String examClass = list.get(0).getExamClass();
            ExamApplyItemDto it2 = new ExamApplyItemDto();
            it2.setApplyNos(applyNos);
            it2.setExamClass(examClass);
            examApplyItemMapper.updateItem(it2);
            DictDeptDto dictDeptDto = new DictDeptDto();
            dictDeptDto.setQueueName(examApplyInfo.getQueueName());
            dictDeptDto.setExamClass(examClass);
            List<DictDept> dictDept = dictDeptService.getPerformDept(dictDeptDto);
            if (dictDept != null && dictDept.size() > 0) {
                ExamApplyDto update = new ExamApplyDto();
                update.setApplyNos(applyNos);
                update.setExamClass(examClass);
                update.setPerformDept(dictDept.get(0).getDeptCode());
                update.setPerformDeptName(dictDept.get(0).getDeptName());
                baseMapper.updateExamApply(update);
            }
        }
        // 将预约成功的消息推送给 pacs
        boolean scheduleMsg = xRayService.sendXRayScheduleMsg(dto.getMergeNo());
        if (!scheduleMsg) {
            throw new Exception("PACS预约失败!");
        }
        return JsonResultUtil.success("成功", examApplyDto);
    }

    /**
     * 修改时段
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult editApm(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo())) {
            return JsonResultUtil.failure("申请单号不能为空");
        }
        if (StringUtils.isBlank(dto.getHospitalCode())) {
            return JsonResultUtil.failure("院区代码不能为空");
        }
        if (StringUtils.isBlank(dto.getScheduleDate())) {
            return JsonResultUtil.failure("预约日期不能为空");
        }
        if (StringUtils.isBlank(dto.getScheduleApm())) {
            return JsonResultUtil.failure("预约时段不能为空");
        }

        ExamApplyDto ea = new ExamApplyDto();
        if (StringUtils.isNotBlank(dto.getPhoneNumber())) {
            ea.setPhoneNumber(dto.getPhoneNumber());
        }
        dto.setSort("1");
        ea.setClassAttr(dto.getClassAttr());
        String isCompliance = commonServiceImpl.mergeRuleForScheduleJudge(ea, dto);
        ea.setItemCode(null); // 实单锁号不需要这个值
        if (StringUtils.isNotBlank(isCompliance)) {
            return JsonResultUtil.failure(isCompliance);
        }

        String itemCode = ea.getItems().get(0).getItemCode();

        // 需要先判断是不是不能取消预约的检查项目
        List<String> examClassList = Arrays.asList(xRayMQConfig.getExamClass().split(","));
        QueryWrapper<DictExamItem> itemQueryWrapper = new QueryWrapper<>();
        itemQueryWrapper.in("EXAM_CLASS", examClassList);
        itemQueryWrapper.eq("ITEM_CODE", itemCode);
        List<DictExamItem> examItems = dictExamItemMapper.selectList(itemQueryWrapper);
        // 如果返回不为空说明是放射科的检查项目，不能取消预约 2025年5月6日： 去掉超声和内镜 ，超声和内镜先取消再预约
        if (!CollectionUtils.isEmpty(examItems) &&
                // 项目类别不属于超声和内镜
                !(Objects.equals(examItems.get(0).getExamClass(), "超声") || Objects.equals(examItems.get(0).getExamClass(), "内镜"))) {
            // 如果返回不为空说明是放射科的检查项目，不能取消预约
            logger.info("放射科预约数据:{}", ea.getItemCode());
            return JsonResultUtil.failure("放射科预约不能修改预约");
        }

        DictUsersDto dictUser = commonServiceImpl.dictUsers(dto);
        ExamApplyDto ex = new ExamApplyDto();
        ex.setTerminalType(dto.getTerminalType());
        ex.setExamClass(ea.getExamClass());
        ex.setUserId(dictUser.getUserId());
        ex.setPassword(dto.getPassword());
        boolean checkPassword = configServiceImpl.isNeedPassWordByDeptsche(ex);
        if (!checkPassword) {
            return JsonResultUtil.failure("密码错误");
        }
        String isLimitSelfOperate = configServiceImpl.isLimitSelfOperate(dto.getTerminalType(),
                ConstantsUtil.ActType.UPDATE.getType(), dto.getStartTime(), ea);
        if (StringUtils.isNotBlank(isLimitSelfOperate)) {
            return JsonResultUtil.failure(isLimitSelfOperate);
        }
        List<String> notices = new ArrayList<String>();
        List<String> itemNameList = new ArrayList<String>();
        for (ExamApplyItemDto item : ea.getItems()) {
            if (StringUtils.isNotBlank(item.getNotice())) {
                notices.add(item.getNotice());
            }
            itemNameList.add(item.getItemName());
        }
        ea.setHospitalCode(dto.getHospitalCode());
        ea.setNewScheduleDate(dto.getScheduleDate());
        ea.setNewScheduleApm(dto.getScheduleApm());
        ea.setOldScheduleDate(ea.getScheduleDate());
        ea.setOldScheduleApm(ea.getScheduleApm());
        ea.setOldQueueName(ea.getQueueName());
        ea.setMergeNo(dto.getMergeNo());
        ea.setTerminalType(dto.getTerminalType());
        ea.setActType(ConstantsUtil.ActType.UPDATE.getType());
        ea.setQueueName(dto.getQueueName());
        ea.setStartTime(dto.getStartTime());
        ea.setEndTime(dto.getEndTime());
        ea.setApplyNos(dto.getApplyNos());
        ea.setClassAttr(dto.getClassAttr());
        ea.setStaffName(dto.getStaffName());
        ea.setEarliestDate(dto.getEarliestDate());
        ea.setEarliestTime(dto.getEarliestTime());
        JsonResult jsonResult = commonServiceImpl.editApm(ea, dictUser);
        // 改约成功，自动签到和发送预约通知
        if (jsonResult.getStatus().equals("0")) {
            // 如果是超声就先取消再预约，有失败就全部回滚
            // 判断是否是超声的检查项目
            // 获取预约信息
            ExamScheduleItemVo scheduleItemVo = examScheduleItemMapper.queryScheduledDate(dto.getApplyNo());
            if (scheduleItemVo.getExamClass().contains("超声") || scheduleItemVo.getExamClass().contains("内镜")) {
                /* 1. 调用取消
                 * 2. 取消成功后再调用预约
                 */
                boolean cancelled = xRayService.cancelScheduleCSMsg(dto.getApplyNo(), dto.getMergeNo());
                if (!cancelled) {
                    throw new RuntimeException("pacs 取消预约失败");
                }
                // 将预约成功的消息推送给 pacs
                boolean scheduleMsg = xRayService.sendXRayScheduleMsg(dto.getMergeNo());
                if (!scheduleMsg) {
                    throw new RuntimeException("pacs 预约失败!");
                }
            }

            String examApm = "";
            Map<String, String> map = (Map<String, String>) jsonResult.getResult();
            ea.setScheduleDate(dto.getScheduleDate());
            ea.setScheduleApm(dto.getScheduleApm());
            ea.setExamApm(examApm);
            ea.setQueueName(map.get("queueName"));
            ExamApplyDto examApplyDto = new ExamApplyDto();
            BeanUtils.copyProperties(ea, examApplyDto);
            examApplyDto.setScheduleDate(dto.getScheduleDate());
            examApplyDto.setScheduledId(ea.getScheduledId());
            examApplyDto.setApplyNo(dto.getApplyNo());
            examApplyDto.setChargeFlag(ea.getChargeFlag());
            examApplyDto.setScheduleStatus("2");
            examApplyDto.setQueueName(map.get("queueName"));
            examApplyDto.setIsPrint(configServiceImpl.isPrint4Schedule(ea) ? "1" : "0");
            examApplyDto.setIsRemindPrint(configServiceImpl.isRemindPrint4Schedule(ea) ? "1" : "0");
            examApplyDto.setIsPrintCode(configServiceImpl.isPrintCode4Schedule(ea) ? "1" : "0");
            DictScheduleApmDto scheduleApm = commonServiceImpl.getTimeEarliest(map.get("apmCode"));
            String timeEarliest = scheduleApm.getTimeEarliest();
            String timeSignin = scheduleApm.getTimeSignin();
            String isSign = configServiceImpl.isScheduleTodayBySign(examApplyDto, scheduleApm) ? "1" : "0";
            examApplyDto.setIsSign(isSign);
            String mergeNo = dto.getMergeNo();
            if (StringUtils.isBlank(dto.getMergeNo())) {
                StringBuffer sb = new StringBuffer();
                for (ExamApplyItemDto examApplyItemDto : examApplyDto.getItems()) {
                    sb.append("," + examApplyDto.getApplyNo() + "-" + examApplyItemDto.getItemNo());
                }
                mergeNo = sb.substring(1);
            }
            examApplyDto.setMergeNo(mergeNo);
            examApplyDto.setTimeEarliest(timeEarliest);
            examApplyDto.setTimeSignin(timeSignin);
            List<String> applyNos = CommonUtil.mergeNo2ApplyNos(mergeNo);
            if (ConstantsUtil.TerminalType.SELF.getType().equals(dto.getTerminalType())
                    || ConstantsUtil.TerminalType.MOBILE.getType().equals(dto.getTerminalType())) {
                ExamApplyItemDto its = new ExamApplyItemDto();
                its.setApplyNos(applyNos);
                its.setScheCancel(1);
                examApplyItemMapper.updateItem(its);
            }
            DictExamQueueDto deq = new DictExamQueueDto();
            deq.setQueueName(ea.getQueueName());
            List<DictExamQueue> list = dictExamQueueService.selectList(deq);
            if (list != null && list.size() > 0) {
                String examClass = list.get(0).getExamClass();
                ExamApplyItemDto it = new ExamApplyItemDto();
                it.setApplyNos(applyNos);
                it.setExamClass(examClass);
                examApplyItemMapper.updateItem(it);
                DictDeptDto dictDeptDto = new DictDeptDto();
                dictDeptDto.setQueueName(ea.getQueueName());
                dictDeptDto.setExamClass(examClass);
                List<DictDept> dictDept = dictDeptService.getPerformDept(dictDeptDto);
                if (dictDept != null && dictDept.size() > 0) {
                    ExamApplyDto update = new ExamApplyDto();
                    update.setApplyNos(applyNos);
                    update.setQueueName(ea.getQueueName());
                    update.setExamClass(examClass);
                    update.setPerformDept(dictDept.get(0).getDeptCode());
                    update.setPerformDeptName(dictDept.get(0).getDeptName());
                    baseMapper.updateExamApply(update);
                }
            }
            if (StringUtils.isBlank(dto.getClassAttr()) && applyNos != null && applyNos.size() > 0) {
                ExamSmsNoticeDto esn = new ExamSmsNoticeDto();
                esn.setApplyNos(applyNos);
                examSmsNoticeService.delete(esn);
            }
            String startTime = "";
            String endTime = "";
            if (StringUtils.isNotBlank(ea.getApmCode())) {
                DictScheduleApm dsa = dictScheduleApmService.selectOneByApmCode(ea.getApmCode());
                endTime = DateUtil.addSecond(dsa.getTimeEnd(), 1);
                endTime = endTime.substring(0, dsa.getTimeEnd().length() - 3);
                startTime = dsa.getTimeStart().substring(0, dsa.getTimeStart().length() - 3);
            }
            List<Map<String, String>> convertSms = CommonUtil.convertSms(notices, dto.getScheduleDate(), startTime,
                    endTime);
            if (CollectionUtils.isNotEmpty(convertSms)) {
                commonServiceImpl.addSmsByItemNotice(ea, convertSms, dto);
            }
            commonServiceImpl.addExamSmsNotice(ea, ConstantsUtil.SmsType.UPDATE.getType(), dto);
            if (configServiceImpl.isDeptNotice(ea.getPatientSource())) {
                DeptNoticeDto deptNoticeDto = new DeptNoticeDto();
                deptNoticeDto.setName(ea.getName());
                deptNoticeDto.setActType(ConstantsUtil.ActType.UPDATE.getType());
                deptNoticeDto.setExamClass(ea.getExamClass());
                deptNoticeDto.setApplyNo(ea.getApplyNo());
                deptNoticeDto.setScheduledDate(ea.getNewScheduleDate());
                deptNoticeDto.setScheduleApm(ea.getNewScheduleApm());
                deptNoticeDto.setOldScheduleDate(ea.getOldScheduleDate());
                deptNoticeDto.setOldScheduleApm(ea.getOldScheduleApm());
                deptNoticeDto.setItemName(String.join(";", itemNameList));
                deptNoticeDto.setApplyNos(ea.getApplyNos());
                deptNoticeDto.setAge(ea.getAge());
                deptNoticeDto.setSex(ea.getSex());
                deptNoticeDto.setDeptName(ea.getPerformDeptName());
                deptNoticeDto.setReqDept(ea.getReqDept());
                deptNoticeDto.setReqWardCode(ea.getReqWardCode());
                deptNoticeService.saveDeptNotice(deptNoticeDto, dictUser);
            }
            return JsonResultUtil.success(jsonResult.getMessage(), examApplyDto);
        }
        return jsonResult;
    }

    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    @Override
    public JsonResult delApm(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo()) && StringUtils.isBlank(dto.getMergeNo())) {
            return JsonResultUtil.failure("申请单号不能为空");
        }
        dto.setActType(ConstantsUtil.ActType.CANCEL.getType());
        ExamApplyDto ea = commonServiceImpl.getApplyForScheduleItem(dto);
        ea = commonServiceImpl.getScheduleToExamApply(dto, ea);

        // 需要先判断是不是不能取消预约的检查项目
        if (xRayMQConfig.getEnable()) {
            List<String> examClassList = Arrays.asList(xRayMQConfig.getExamClass().split(","));
            QueryWrapper<DictExamItem> itemQueryWrapper = new QueryWrapper<>();
            itemQueryWrapper.in("EXAM_CLASS", examClassList);
            itemQueryWrapper.eq("ITEM_CODE", ea.getItemCode());
            List<DictExamItem> examItems = dictExamItemMapper.selectList(itemQueryWrapper);
            // 如果返回不为空说明是放射科的检查项目，不能取消预约
            // 01为锁定状态，可以放行，其他状态不能取消预约
            if (!CollectionUtils.isEmpty(examItems) && (!"01".equals(ea.getScheduleStatus()))) {
                String examClass = examItems.get(0).getExamClass();
                if (!"超声".equals(examClass)) {
                    logger.info("放射科预约数据:{}", ea.getItemCode());
                    return JsonResultUtil.failure(examClass + "检查类别不能取消预约");
                }
            }
        }

        DictUsersDto dictUser = commonServiceImpl.dictUsers(dto);
        if (!"01".equals(ea.getScheduleStatus()) && !"2".equals(dto.getIsCancel())) {
            ExamApplyDto ex = new ExamApplyDto();
            ex.setTerminalType(dto.getTerminalType());
            ex.setExamClass(ea.getExamClass());
            ex.setUserId(dictUser.getUserId());
            ex.setPassword(dto.getPassword());
            boolean checkPassword = configServiceImpl.isNeedPassWordByDeptsche(ex);
            if (!checkPassword) {
                return JsonResultUtil.failure("密码错误");
            }
        }
        if (StringUtils.isNotBlank(ea.getExamStatus())) {
            ea.setScheduleStatus(ea.getExamStatus());
        }
        if (StringUtils.isNotBlank(ea.getDesc())) {
            return JsonResultUtil.failure(ea.getDesc());
        }
        if ("10".equals(ea.getScheduleStatus()) || StringUtils.isBlank(ea.getScheduleDate())
                || StringUtils.isBlank(ea.getScheduledId())) {
            return JsonResultUtil.failure("预约状态已改变，请刷新后重试！");
        }
        String isLimitSelfOperate = configServiceImpl.isLimitSelfOperate(dto.getTerminalType(),
                ConstantsUtil.ActType.CANCEL.getType(), dto.getStartTime(), ea);
        if (StringUtils.isNotBlank(isLimitSelfOperate)) {
            return JsonResultUtil.failure(isLimitSelfOperate);
        }
        if (!dto.getApplyNo().startsWith("RE") && "08".equals(ea.getScheduleStatus())) {
            JsonResult recedeCostResult = commonServiceImpl.recedeCost(ea, ConstantsUtil.ActType.CANCEL.getType(),
                    dictUser);
            if (recedeCostResult != null && !"0".equals(recedeCostResult.getStatus())) {
                return JsonResultUtil.failure(recedeCostResult.getMessage());
            }
            boolean isNotUpdateChargeFlagByRecedeCost = configServiceImpl
                    .isOpenConfig(ConstantsUtil.ConfigName.IS_NOT_UPDATE_CHARGE_FLAG_BY_RECEDE_COST.getKey());
            if (recedeCostResult != null && "0".equals(recedeCostResult.getStatus())
                    && !isNotUpdateChargeFlagByRecedeCost) {
                ExamApplyDto e = new ExamApplyDto();
                e.setApplyNos(CommonUtil.mergeNo2ApplyNos(dto.getMergeNo()));
                e.setQueueName(ea.getQueueName());
                e.setChargeFlag("0");
                baseMapper.updateExamApply(e);
            }
            for (ExamApplyItem items : ea.getItems()) {
                if (items.getScheCancel() == null) {
                    ExamApplyItem eai = new ExamApplyItem();
                    eai.setApplyNo(items.getApplyNo());
                    eai.setItemNo(items.getItemNo());
                    eai.setScheCancel(0);
                    examApplyItemServiceImpl.updateItem(eai);
                }
            }
        }
        List<String> applyNos = CommonUtil.mergeNo2ApplyNos(dto.getMergeNo());
        if (StringUtils.isBlank(dto.getClassAttr()) && !CollectionUtils.isEmpty(applyNos)) {
            ExamSmsNoticeDto esn = new ExamSmsNoticeDto();
            esn.setApplyNos(applyNos);
            examSmsNoticeService.delete(esn);
        }
        if (StringUtils.isNotBlank(ea.getScheduleStatus()) && !"01".equals(ea.getScheduleStatus())
                && !dto.getApplyNo().startsWith("RE") && !"1".equals(dto.getIsSend())) {
            commonServiceImpl.addExamSmsNotice(ea, ConstantsUtil.SmsType.CANCLE_SCHEDULE.getType(), dto);
        }
        Double reqCount = 1.0;
        if (ea.getIsExamClass4Organ()) {
            reqCount = commonServiceImpl.getOrgansReqCount(ea);
            if (reqCount == null) {
                reqCount = commonServiceImpl.getReqOrganByItems(ea.getItems());
            }
        }
        // 取消预约结果
        boolean delResultFlag;
        ExamApplyDto eaDto = new ExamApplyDto();
        eaDto.setOrgans(ea.getOrgans());
        eaDto.setApplyNo(ea.getApplyNo());
        eaDto.setScheduleDate(ea.getScheduleDate());
        eaDto.setScheduledId(ea.getScheduledId());
        eaDto.setNextApmRatio(ea.getNextApmRatio());
        eaDto.setMergeNo(ea.getMergeNo());
        eaDto.setReqCount(reqCount);
        eaDto.setRegularIdList(ea.getRegularIdList());
        eaDto.setApmCode(ea.getApmCode());
        if ("08".equals(ea.getScheduleStatus())) {
            eaDto.setExamClass(ea.getExamClass());
            eaDto.setTerminalType(dto.getTerminalType());
        }
        if (dto.getApplyNo().startsWith("RE")) {
            delResultFlag = delExamRefer(eaDto, ea.getIsExamClass4Organ());
        } else {
            // 删除预约操作
            delResultFlag = delExamSchedule(eaDto, ea.getIsExamClass4Organ());
        }
        if (!delResultFlag) {
            return JsonResultUtil.failure("取消超时,请重试或到护士站咨询");
        }
        String actType = ConstantsUtil.ActType.CANCEL.getType();
        if ("01".equals(ea.getScheduleStatus())) {
            actType = "U";
        } else {
            // 如果是取消预约并且取消类型是超声，需要调用pacs进行取消预约，按照pacs的返回结果进行提交或者回滚操作
            List<String> examClass = mqConfig.getCsCancelRequest().getExamClass();
            if (mqConfig.getCsCancelRequest().isEnable()
                    && CollectionUtils.isNotEmpty(examClass)) {
                QueryWrapper<DictExamItem> itemQueryWrapper = new QueryWrapper<>();
                itemQueryWrapper.in("EXAM_CLASS", examClass);
                itemQueryWrapper.eq("ITEM_CODE", ea.getItemCode());
                List<DictExamItem> examItems = dictExamItemMapper.selectList(itemQueryWrapper);
                if (!CollectionUtils.isEmpty(examItems)) {
                    // 构建消息体并推送
                    boolean cancelFlag = xRayService.cancelScheduleCSMsg(dto.getApplyNo(), dto.getMergeNo());
                    if (!cancelFlag) {
                        throw new RuntimeException("pacs 取消预约失败");
                    }
                }
            }
        }
        ea.setProcess(eaDto.getProcess());
        ea.setNextOrganProcess(eaDto.getNextOrganProcess());
        ea.setTerminalType(dto.getTerminalType());
        ea.setActType(actType);
        ea.setActDescription(dto.getActDescription());
        ea.setCancelMemo(dto.getCancelMemo());
        // 添加预约申请单的操作日志
        commonServiceImpl.addExamScheduleAct(ea, dictUser);
        ea.setType(ConstantsUtil.ActType.CANCEL.getType());

        // 推送部门消息
        if (ConstantsUtil.ActType.CANCEL.getType().equals(actType)
                && configServiceImpl.isDeptNotice(ea.getPatientSource())) {
            List<String> itemNameList = new ArrayList<String>();
            for (ExamApplyItemDto item : ea.getItems()) {
                itemNameList.add(item.getItemName());
            }
            DeptNoticeDto deptNoticeDto = new DeptNoticeDto();
            deptNoticeDto.setName(ea.getName());
            if (StringUtils.isNotBlank(dto.getNewScheduleDate())) {
                deptNoticeDto.setActType(ConstantsUtil.ActType.UPDATE.getType());
                deptNoticeDto.setScheduledDate(dto.getNewScheduleDate());
                deptNoticeDto.setScheduleApm(dto.getNewScheduleApm());
            } else {
                deptNoticeDto.setActType(ConstantsUtil.ActType.CANCEL.getType());
            }
            deptNoticeDto.setApplyNo(ea.getApplyNo());
            deptNoticeDto.setOldScheduleDate(ea.getScheduleDate());
            deptNoticeDto.setOldScheduleApm(ea.getScheduleApm());
            deptNoticeDto.setExamClass(ea.getExamClass());
            deptNoticeDto.setItemName(String.join(";", itemNameList));
            deptNoticeDto.setApplyNos(ea.getApplyNos());
            deptNoticeDto.setAge(ea.getAge());
            deptNoticeDto.setSex(ea.getSex());
            deptNoticeDto.setDeptName(ea.getPerformDeptName());
            deptNoticeDto.setReqDept(ea.getReqDept());
            deptNoticeDto.setReqWardCode(ea.getReqWardCode());
            deptNoticeService.saveDeptNotice(deptNoticeDto, dictUser);
        }
        // 取消预约成功，修改scheduleStatus
        ea.setScheduleStatus(ConstantsUtil.ScheduleStatus.ZERO.getStatus());
        ea.getItems().forEach(x -> {
            x.setScheduleStatus(ConstantsUtil.ScheduleStatus.ZERO.getStatus());
        });
        return JsonResultUtil.success("成功", ea);
    }

    @Override
    public JsonResult getExamSchedules(ExamApplyDto dto) {
        configServiceImpl.toUpperCaseInput(dto);
        if (StringUtils.isNotBlank(dto.getIcCard()) || StringUtils.isNotBlank(dto.getSickId())
                || StringUtils.isNotBlank(dto.getOutpatientNo()) || StringUtils.isNotBlank(dto.getApplyNo())
                || StringUtils.isNotBlank(dto.getCommonCard())) {
            commonServiceImpl.getHisApplyByThirdUrl(dto);
        }
        if (StringUtils.isNotBlank(dto.getIcCard())) {
            dto.setCommonCard(dto.getIcCard());
        }
        if (StringUtils.isNotBlank(dto.getCommonCard())) {
            List<String> sickIds = commonServiceImpl.getSickIds(dto);
            if (sickIds.size() == 0) {
                return JsonResultUtil.failure("没有您的检查申请记录,如有疑问请到护士站咨询");
            }
            dto.setSickIds(sickIds);
        }
        dto.setReqDepts(CommonUtil.split2List(dto.getDeptCode()));
        dto.setReqWardCodes(CommonUtil.split2List(dto.getWardCode()));
        dto.setPatientSources(CommonUtil.split2List(dto.getPatientSource()));
        dto.setExamClasses(dictExamClassService.getExamClass(dto.getExamClass()));
        dto.setApmFlags(CommonUtil.split2List(dto.getApmFlag()));
        dto.setNurseUnits(CommonUtil.split2List(dto.getNurseUnit()));
        // List<String> StatusList = CommonUtil.split2List(dto.getScheduleStatus());
        List<String> transTools = CommonUtil.split2List(dto.getTransTool());
        List<String> accomExams = CommonUtil.split2List(dto.getAccomExam());
        List<String> toolAccom = new ArrayList<String>();
        if (!transTools.isEmpty() && !accomExams.isEmpty()) {
            transTools.forEach(tool -> accomExams.forEach(accom -> toolAccom.add(tool + "|" + accom)));
            dto.setToolAccoms(toolAccom);
        } else if (!transTools.isEmpty()) {
            dto.setTransTools(transTools);
        } else if (!accomExams.isEmpty()) {
            dto.setAccomExams(accomExams);
        }
        if (dto.getExamItemFlags() != null) {
            String underLineFlags = CommonUtil.convertItemFlagsCondition(dto.getExamItemFlags());
            dto.setFlags(underLineFlags);
        }
        // 将前端的状态转成检查状态
        List<String> statuses = new ArrayList<String>();
        for (String s : CommonUtil.split2List(dto.getScheduleStatus())) {
            statuses.add(CommonUtil.convertScheduleStatus(s));
        }
        dto.setScheduleStatuses(statuses);
        String isQueryYetExam = configServiceImpl.getConfigByName(ConstantsUtil.ConfigName.YY_QUERY_YET_EXAMS.getKey());
        if (StringUtils.isNotBlank(isQueryYetExam) && "1".equals(dto.getNurseFlag())) {
            dto.setIsQueryYetExam(isQueryYetExam);
        }
        String isVisitdateSort = configServiceImpl
                .getConfigByName(ConstantsUtil.ConfigName.YY_VISIT_DATE_SORT.getKey());
        if (StringUtils.isNotBlank(isVisitdateSort)
                && (ConstantsUtil.TerminalType.CLINIC_IN.getType().equals(dto.getTerminalType())
                || ConstantsUtil.TerminalType.CLINIC_OUT.getType().equals(dto.getTerminalType()))) {
            dto.setIsVisitDateSort(isVisitdateSort);
        }
        dto.setNotExamClasses(configServiceImpl.getNotExamClassList());
        String noShowTerminalType = configServiceImpl
                .getConfigByName(ConstantsUtil.ConfigName.NO_SHOW_UN_SCHEDULE_ITEM_BY_TERMINAL_TYPE.getKey());
        if (StringUtils.isNotBlank(noShowTerminalType) && noShowTerminalType.contains(dto.getTerminalType())) {
            dto.setNoShowTerminalType("1");
        }
        String customExcelSortSetConfigName = "";
        String terminalType = dto.getTerminalType();
        boolean isClinic = false;
        if (StringUtils.isNotBlank(terminalType) &&
                (ConstantsUtil.TerminalType.CLINIC_IN.getType().equals(terminalType)
                        || ConstantsUtil.TerminalType.CLINIC_OUT.getType().equals(terminalType))) {
            isClinic = true;
        }
        if ("1".equals(dto.getQueryTag())) {
            customExcelSortSetConfigName = ConstantsUtil.ConfigName.YY_CUSTOMEXCEL_SORT_SET.getKey();
            if (isClinic) {
                customExcelSortSetConfigName = ConstantsUtil.ConfigName.YY_CUSTOMEXCEL_SORT_SET_BY_DEPTSCHE.getKey();
            }
        } else if ("2".equals(dto.getQueryTag())) {
            customExcelSortSetConfigName = ConstantsUtil.ConfigName.YY_PRINT_LIST_SORT_SET.getKey();
            if (isClinic) {
                customExcelSortSetConfigName = ConstantsUtil.ConfigName.YY_PRINT_LIST_SORT_SET_BY_DEPTSCHE.getKey();
            }
            dto.setApplyNos(CommonUtil.split2List(dto.getApplyNo()));
            dto.setApplyNo(null);
        } else if ("3".equals(dto.getQueryTag())) {
            customExcelSortSetConfigName = ConstantsUtil.ConfigName.YY_CURE_CUSTOMEXCEL_SORT_SET.getKey();
        } else if (StringUtils.isBlank(dto.getQueryTag()) && StringUtils.isBlank(dto.getSort())) {
            customExcelSortSetConfigName = ConstantsUtil.ConfigName.CUSTOM_TABLE_ROW_SORT_SET_BY_MULTIPLE_QUERY
                    .getKey();
            if (isClinic) {
                customExcelSortSetConfigName = ConstantsUtil.ConfigName.CUSTOM_TABLE_ROW_SORT_SET_BY_DEPTSCHE.getKey();
            }
        }
        String customExcelSortSetStr = configServiceImpl.getConfigByName(customExcelSortSetConfigName);
        if (StringUtils.isNotBlank(customExcelSortSetStr)) {
            ConfigDto.SortSet customExcelSortSet = JsonUtil.toBean(customExcelSortSetStr, ConfigDto.SortSet.class);
            if (customExcelSortSet != null) {
                String sortField1 = customExcelSortSet.getSortField();
                String sortOrder1 = customExcelSortSet.getSortOrder();
                String sortField2 = customExcelSortSet.getSortField2();
                String sortOrder2 = customExcelSortSet.getSortOrder2();
                String sortFieldOrderStr = CommonUtil.convertSql(sortField1, sortOrder1, sortField2, sortOrder2);
                dto.setSortFieldOrderStr(sortFieldOrderStr);
            }
        }
        String sort_order = dto.getSortOrder();
        if (StringUtils.isNotBlank(dto.getSort())) {
            if ("0".equals(dto.getSort())) {
                sort_order = "asc";
            } else {
                sort_order = "desc";
            }
        }
        if (StringUtils.isBlank(dto.getApplyType())) {
            dto.setApplyType("1");
        }
        dto.setSortOrder(sort_order);
        Page<?> page = null;
        if (dto.getPageSize() != null) {
            page = PageHelper.startPage(dto.getPageNo(), dto.getPageSize());
        }
        List<ExamApplyDto> list = baseMapper.getExamSchedules(dto);
        List<ExamApplyDto> newList = new ArrayList<>();
        if (list.size() < 500) {
            newList = commonServiceImpl.mergeApply(list, "", dto.getTerminalType(), dto.getIsMergeChannel());
        } else {
            int len = 500;
            int size = list.size();
            for (int count = (len + size - 1) / len, i = 0; i < count; ++i) {
                // Integer min = ((i + 1) * len > size) ? size : (len * (i + 1));
                List<ExamApplyDto> subList = list.subList(i * len, Math.min((i + 1) * len, size));
                newList.addAll(commonServiceImpl.mergeApply(list, "", dto.getTerminalType(), dto.getIsMergeChannel()));
            }
        }
        commonServiceImpl.assembleResult(newList, dto);
        PageVO pageVO = new PageVO();
        if (dto.getPageSize() != null && Objects.nonNull(page)) {
            pageVO.setPageNo(dto.getPageNo());
            pageVO.setPageSize(dto.getPageSize());
            pageVO.setTotal(page.getTotal());
            pageVO.setPages(page.getPages());
        }
        return JsonResultUtil.success("成功", newList, pageVO);
    }

    @Override
    public JsonResult delScheduleApmMulti(ExamScheduleDto dto) {
        if (!StringUtils.isNotBlank(dto.getApplyNo())) {
            return JsonResultUtil.failure("申请单号不能为空");
        }
        List<ExamApplyDto> syncList = new ArrayList<ExamApplyDto>();
        StringBuffer errMsgs = new StringBuffer();
        String[] split = dto.getApplyNo().split("，");
        for (String applyNo : split) {
            String[] arr = applyNo.split("=");
            String applyNoVal = StringUtils.isNotBlank(arr[0]) ? arr[0] : "";
            String mergeNo = StringUtils.isNotBlank(arr[1]) ? arr[1].replaceAll("；", ",") : "";
            ExamApplyDto examApplyDto = new ExamApplyDto();
            examApplyDto.setApplyNo(applyNoVal);
            examApplyDto.setTerminalType(dto.getTerminalType());
            examApplyDto.setMergeNo(mergeNo);
            JsonResult jsonResult = null;
            String scheduleStatus = StringUtils.isNotBlank(arr[2]) ? arr[2] : "";
            if (StringUtils.isNotBlank(scheduleStatus)) {
                if ("1".equals(scheduleStatus) || "2".equals(scheduleStatus)) {
                    examApplyDto.setIsSend(dto.getIsSend());
                    examApplyDto.setIsCancel("2");
                    jsonResult = delApm(examApplyDto);
                } else if ("3".equals(scheduleStatus)) {
                    // 业务需求已报到的病人不允许取消
                    return JsonResultUtil.failure("该病人已经报到，无法取消！");
                    // jsonResult = delSign(examApplyDto);
                }
            }
            if (jsonResult != null) {
                if ("0".equals(jsonResult.getStatus())) {
                    ExamApplyDto ea = (ExamApplyDto) jsonResult.getResult();
                    if (!"01".equals(ea.getScheduleStatus())) {
                        syncList.add(ea);
                    }
                    if ("1".equals(dto.getIsSend()) && "08".equals(ea.getScheduleStatus())) {
                        String smsType = ConstantsUtil.SmsType.CANCLE_SCHEDULE.getType();
                        ExamSmsNotice esn = new ExamSmsNotice();
                        esn.setSmsNo(dictSerialService.getSerialId("SMS_NO"));
                        esn.setApplyNo(ea.getApplyNo());
                        esn.setSmsType(smsType);
                        esn.setSmsSign("预约详情");
                        HashMap<String, Object> map = new HashMap<String, Object>();
                        commonServiceImpl.converPatternMap(ea, map, examApplyDto, smsType);
                        esn.setSmsContent(CommonUtil.replaceMsg(dto.getSmsMemo(), map));
                        esn.setPhoneNumber(ea.getPhoneNumber());
                        esn.setCreateDate(DateUtil.getCurrDateStr());
                        esn.setCreateTime(DateUtil.getCurrentTime());
                        examSmsNoticeService.insert(esn);
                    }
                } else {
                    errMsgs.append("，" + applyNoVal);
                }
            } else {
                errMsgs.append("，" + applyNoVal);
            }
        }
        if (StringUtils.isNotBlank(errMsgs.toString())) {
            return JsonResultUtil.failure("0", "[" + errMsgs.substring(1) + "]申请单取消失败", syncList);
        }
        return JsonResultUtil.success(syncList);
    }

    /***
     * signin 签到
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult signinSchedule(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo())
                && StringUtils.isBlank(dto.getIcCard())
                && StringUtils.isBlank(dto.getSickId())
                && StringUtils.isBlank(dto.getCommonCard())) {
            return JsonResultUtil.failure("申请单号不能为空");
        }
        dto.setCommonCard(configServiceImpl.icCardPre(dto.getCommonCard()));
        ExamApplyDto eaDto = commonServiceImpl.getApplyNos(dto);
        List<String> applyNos = eaDto.getApplyNos();
        dto.setApplyNo(dto.getApplyNo().split(",")[0]);
        // 获取申请单信息
        ExamApplyDto ea = commonServiceImpl.getExamApplyInfo(dto.getApplyNo(), dto.getTerminalType());
        if (ea == null) {
            return JsonResultUtil.failure("没有预约申请或预约已被取消");
        }
        commonServiceImpl.getScheduleToExamApply(dto, ea);
        List<ExamApplyItemDto> items = commonServiceImpl.getExamApplyItem(dto.getMergeNo(), ea);
        String terminalType = dto.getTerminalType();
        // 判断是否可以自助签到
        if (CollectionUtils.isNotEmpty(items)
                && (ConstantsUtil.TerminalType.SELF.getType().equals(terminalType)
                || ConstantsUtil.TerminalType.MOBILE.getType().equals(terminalType))) {
            String hasNoSignSelfItemStr = commonServiceImpl.hasNoSignSelfItem(items);
            if (StringUtils.isNotBlank(hasNoSignSelfItemStr)) {
                return JsonResultUtil.failure("您的检查申请 " + applyNos + " " + hasNoSignSelfItemStr + "。如有疑问请到护士站咨询!");
            }
        }
        // 检查是否可以重复报道的类别
        boolean isRepeatSign4Self = false;
        if (ConstantsUtil.TerminalType.SELF.getType().equals(terminalType)) {
            List<String> repeatSignByExamClassList = configServiceImpl
                    .getConfigListByName(ConstantsUtil.ConfigName.REPEAT_SIGN_BY_EXAM_CLASS.getKey());
            isRepeatSign4Self = repeatSignByExamClassList.contains(ea.getExamClass());
        }
        // 已报到或者不可重复报到的类型直接返回
        if ("10".equals(ea.getExamStatus()) && !isRepeatSign4Self) {
            return JsonResultUtil.failure("申请单已报到");
        }
        if (StringUtils.isNotBlank(ea.getExamStatus()) && Integer.parseInt(ea.getExamStatus()) >= 10
                && !isRepeatSign4Self) {
            return JsonResultUtil.failure("该申请单已报到或已检查!");
        }

        ExamApplyDto examApplyDto = new ExamApplyDto();
        BeanUtils.copyProperties(ea, examApplyDto);
        // 申请单预约的检查日期
        String scheduleDateStr = ea.getScheduleDate();
        Date scheduleDate = DateUtil.parse(scheduleDateStr, DateUtil.FORMAT_DATE);
        String scheduleApm = ea.getScheduleApm();
        // 判断签到时间
        Map<String, Object> map = commonServiceImpl.judgeTimeSignin(ea);
        boolean isStartTime = (boolean) map.get("isStartTime");
        boolean isEndTime = (boolean) map.get("isEndTime");
        // 最早签到时间 HH:mm:ss
        String timeEarliest = map.get("timeEarliest").toString();
        // 最早签到日期 yyyy-MM-dd
        String dateEarliest = map.get("dateEarliest").toString();

        String operator;
        DictUsersDto user = new DictUsersDto();
        // 获取操作人信息
        if (ConstantsUtil.TerminalType.SELF.getType().equals(terminalType)
                || ConstantsUtil.TerminalType.MOBILE.getType().equals(terminalType)
                || ConstantsUtil.TerminalType.SYSTEM.getType().equals(terminalType)) {
            operator = CommonUtil.convertTerminalType(terminalType);
            user.setUserId(StringUtils.isNotBlank(dto.getUserId()) ? dto.getUserId() : terminalType);
            user.setName(dto.getUserName());
        } else {
            user = commonServiceImpl.dictUsers(dto);
            operator = user.getUserId();
        }
        ea.setUserId(user.getUserId());
        ea.setUserName(user.getName());
        ea.setStaffNo(user.getStaffNo());

        // 是关闭签到时间限制 true 开启 false 关闭
        boolean noSinginTimeLimit = configServiceImpl
                .isOpenConfig(ConstantsUtil.ConfigName.IS_SIGNIN_TIME_NO_LIMIT.getKey());
        // 有签到限制 并且 晚于最晚签到时间 且 来源是自助机
        if (!noSinginTimeLimit
                && isEndTime
                && ConstantsUtil.TerminalType.SELF.getType().equals(terminalType)) {
            if (StringUtils.isNotBlank(ea.getExamStatus())) {
                if (isRepeatSign4Self) {
                    String queueNo = ea.getQueueNo();
                    String queueName = ea.getQueueName();
                    String location = ea.getLocation();
                    if (CollectionUtils.isNotEmpty(items)) {
                        ExamApplyItemDto itemDto = items.get(0);
                        queueNo = itemDto.getQueueNo();
                        queueName = itemDto.getExamQueueName();
                        location = itemDto.getLocation();
                    }
                    String errMsg;
                    if (StringUtils.isBlank(dto.getApplication())) {
                        errMsg = "您今天的" + ea.getExamClass() + "检查预约已超时不能重复报到了，<br/>【已报到信息】<br/>排队号：" + queueNo
                                + "<br/>预约时间：" + ea.getScheduleDate() + "<br/>预约时段：" + ea.getScheduleApm()
                                + "<br/>检查队列：" + queueName + "<br/>检查地点：" + location;
                    } else {
                        errMsg = "您今天的" + ea.getExamClass() + "检查预约已超时不能重复报到了，【已报到信息】排队号：" + queueNo + "，预约时间："
                                + ea.getScheduleDate() + "，预约时段：" + ea.getScheduleApm() + "，检查队列：" + queueName
                                + "，检查地点：" + location;
                    }
                    return JsonResultUtil.failure(errMsg);
                }
            } else {
                ExamSchedule examSchedule = new ExamSchedule();
                examSchedule.setScheduledId(ea.getScheduledId());
                examSchedule.setSigninOvertimeCnt(1);
                examScheduleService.editExamScheduleById(examSchedule);

                int signinOvertimeLimit = configServiceImpl.getSigninOvertimeLimit();
                int signinOvertimeCnt = examScheduleMapper.getSigninOvertimeCnt(ea);
                if (signinOvertimeCnt > signinOvertimeLimit) {
                    ExamPatientLock examPatientLock = new ExamPatientLock();
                    examPatientLock.setSickId(ea.getSickId());
                    examPatientLock.setName(ea.getName());
                    examPatientLock
                            .setIcCard(StringUtils.isNotBlank(ea.getIcCard()) ? ea.getIcCard() : ea.getInpatientNo());
                    examPatientLock.setIdentityCard(ea.getIdentityCard());
                    examPatientLock.setUserId(user.getUserId());
                    examPatientLock.setUserName(user.getName());
                    examPatientLock.setMemo("由于检查预约报到超时超过" + signinOvertimeLimit + "次");
                    // 添加患者黑名单
                    examPatientLockService.addPatientLock(examPatientLock);
                    examScheduleMapper.updateSigninOvertimeCnt2Zero(ea);
                    return JsonResultUtil.failure("报到失败,由于报到超时" + signinOvertimeLimit + "次您已被加入黑名单。如有疑问请到护士站咨询!");
                }
                return JsonResultUtil
                        .failure("您的检查预约报到超时,请重新预约。如有疑问请到护士站咨询![注意:报到超时超过" + signinOvertimeLimit + "次，将被加入黑名单，影响预约。");
            }
        }

        // 是否强制报到 false：非强制签到 true：强制签到
        boolean signInLimit = false;
        boolean isTerminalType = ConstantsUtil.TerminalType.DEPT.getType().equals(terminalType)
                || ConstantsUtil.TerminalType.SCHEDULE_CENTER.getType().equals(terminalType)
                || ConstantsUtil.TerminalType.SCHEDULE_MANAGE.getType().equals(terminalType);
        if ("1".equals(dto.getSignInLimit()) && isTerminalType) {
            signInLimit = true;
        }
        // 非强制签到 且 早于最早报到时间
        if (!signInLimit && isStartTime) {
            Date currDate = DateUtil.getCurrDate();
            Date earliestDateSign = DateUtil.parse(dateEarliest, DateUtil.FORMAT_DATE);
            // 当前日期 超过最早签到日期 且小于预约报到的日期（非报到当天）
            if (currDate.compareTo(earliestDateSign) >= 0 && currDate.compareTo(scheduleDate) <= 0) {
                if ("0".equals(dto.getSignInLimit())) {
                    examApplyDto.setIsSign("1");
                    examApplyDto.setScheduleDate(scheduleDateStr);
                    examApplyDto.setScheduleApm(scheduleApm);
                    return JsonResultUtil.success("该检查预约时间是:" + scheduleDateStr + " " + scheduleApm + "，最早可在"
                            + dateEarliest + " " + timeEarliest + "后报到！", examApplyDto);
                }
                return JsonResultUtil.failure("该检查预约时间是" + scheduleDateStr + " " + scheduleApm + "，最早可在" + dateEarliest
                        + " " + timeEarliest + "后报到！");
            } else {
                String str = "请在预约日期当天报到！";
                if (!dateEarliest.equals(scheduleDateStr)) {
                    str = "最早可在" + dateEarliest + "后报到";
                }
                if ("0".equals(dto.getSignInLimit())) {
                    examApplyDto.setIsSign("1");
                    examApplyDto.setScheduleDate(scheduleDateStr);
                    examApplyDto.setScheduleApm(scheduleApm);
                    return JsonResultUtil.success("该检查预约日期是" + scheduleDateStr + "，" + str, examApplyDto);
                }
                return JsonResultUtil.failure("该检查预约日期是" + scheduleDateStr + "，" + str);
            }
        } else if (!signInLimit && isEndTime && !noSinginTimeLimit) {
            if ("0".equals(dto.getSignInLimit())) {
                examApplyDto.setIsSign("1");
                examApplyDto.setScheduleDate(scheduleDateStr);
                examApplyDto.setScheduleApm(scheduleApm);
                return JsonResultUtil.success("该检查已错过报到时间，请修改预约！", examApplyDto);
            }
            return JsonResultUtil.failure("该检查已错过报到时间，请修改预约！");
        } else {
            JsonResult confirmFeeBeforeSignResult = commonServiceImpl.confirmFeeBeforeSign(ea,
                    ConstantsUtil.ActType.SIGN.getType(), user);
            if (confirmFeeBeforeSignResult != null && !"0".equals(confirmFeeBeforeSignResult.getStatus())) {
                return JsonResultUtil.failure(confirmFeeBeforeSignResult.getMessage());
            }
            String chargeFlag = commonServiceImpl.getChargeFlag(ea);
            String patientSource = configServiceImpl.getPatientSourceIn();
            if (!StringUtils.isNotBlank(patientSource)) {
                return JsonResultUtil.failure("未配置住院病人来源名称");
            }
            String isNoChargeNoSignStr = configServiceImpl
                    .getConfigByName(ConstantsUtil.ConfigName.IS_NO_CHARGE_NO_SIGN.getKey());
            if ((StringUtils.isBlank(isNoChargeNoSignStr) || "0".equals(isNoChargeNoSignStr))
                    && !patientSource.equals(ea.getPatientSource())
                    && !"急诊".equals(ea.getPatientSource()) && "0".equals(chargeFlag)) {
                logger.error("检查申请没有结算applyNo:" + ea.getApplyNo());
                return JsonResultUtil.failure("该检查申请未缴费,不能报到");
            }
            if (!patientSource.equals(ea.getPatientSource())
                    && !"急诊".equals(ea.getPatientSource())
                    && "2".equals(chargeFlag)) {
                logger.error("检查申请没有结算applyNo:" + ea.getApplyNo());
                return JsonResultUtil.failure("该检查申请已作废或已退费,不能报到");
            }
            ea.setItems(items);
            ea.setMergeNo(dto.getMergeNo());
            ea.setTerminalType(dto.getTerminalType());
            String signParam = ea.getScheduledId() + "," + operator + "," + dto.getMergeNo();
            // 签到
            SignScheduleDto signScheduleDto = commonServiceImpl.signSchedule(signParam, ea);
            logger.info("【报道】 APPLY_NO：" + ea.getApplyNo() + "; desc: " + signScheduleDto.getDesc());
            if (!"0".equals(signScheduleDto.getCode())) {
                return JsonResultUtil.failure("报到失败," + signScheduleDto.getDesc() + "如有疑问请到护士站咨询！");
            }
            if (StringUtils.isBlank(signScheduleDto.getQueueNo())) {
                return JsonResultUtil.failure("报到失败,没有排队号!");
            }
            String queueNo2 = signScheduleDto.getQueueNo();
            String waitCount = signScheduleDto.getWaitCount();
            String patLocalId = signScheduleDto.getPatLocalId();
            String queueName4Sj = signScheduleDto.getQueueName();
            String location4Sj = signScheduleDto.getLocation();
            String examNo = signScheduleDto.getExamNo();
            ea.setTerminalType(dto.getTerminalType());
            ea.setActType(ConstantsUtil.ActType.SIGN.getType());
            commonServiceImpl.addExamScheduleAct(ea, commonServiceImpl.dictUsers(dto));
            examApplyDto.setIsPrint(configServiceImpl.isPrint4Sign(ea) ? "1" : "0");
            examApplyDto.setIsRemindPrint(configServiceImpl.isRemindPrint4Sign(ea) ? "1" : "0");
            examApplyDto.setExamNo(examNo);
            examApplyDto.setWaitCount(waitCount);
            examApplyDto.setExamQueueName(StringUtils.isNotBlank(queueName4Sj) ? queueName4Sj : ea.getExamQueueName());
            examApplyDto.setQueueNo(queueNo2);
            examApplyDto.setLocation(StringUtils.isNotBlank(location4Sj) ? location4Sj : ea.getLocation());
            examApplyDto.setPatLocalId(patLocalId);
            examApplyDto.setScheduleStatus(ConstantsUtil.ActType.SIGN.getType());
            examApplyDto.setScheduledId(ea.getScheduledId());
            examApplyDto.setMergeNo(dto.getMergeNo());
            examApplyDto.setApplyNos(applyNos);
            examApplyDto.setActType(ConstantsUtil.ActType.SIGN.getType());
            examApplyDto.setTerminalType(dto.getTerminalType());
            commonServiceImpl.addExamSmsNotice(ea, ConstantsUtil.SmsType.SIGNIN.getType(), dto);
            return JsonResultUtil.success("成功", examApplyDto);
        }
    }

    @Override
    public JsonResult signInScheduledMulti(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getMergeNo())) {
            return JsonResultUtil.success("您没有当天可报到的检查申请单请确认您的预约信息");
        }
        List<ExamApplyDto> isSignInItem = new ArrayList<ExamApplyDto>();
        List<String> list = Arrays.asList(dto.getMergeNo().split("="));
        for (String mergeNos : list) {
            String[] mergeNoArr = mergeNos.split(",");
            String applyno = "";
            String hospitalCode = "";
            String scheduleDate = "";
            String scheduleApm = "";
            StringBuffer itemNames = new StringBuffer();
            for (String mergeNo : mergeNoArr) {
                applyno = mergeNo.substring(0, mergeNo.lastIndexOf("-"));
                String itemNo = mergeNo.substring(mergeNo.lastIndexOf("-") + 1);
                ExamApplyDto ead = new ExamApplyDto();
                ead.setApplyNo(applyno);
                ead.setItemNo((long) Integer.parseInt(itemNo));
                List<ExamApplyDto> eaList = baseMapper.getExamSchedule(ead);
                for (ExamApplyDto ea : eaList) {
                    hospitalCode = ea.getScheduleHospital();
                    scheduleDate = ea.getScheduleDate();
                    scheduleApm = ea.getScheduleApm();
                    itemNames.append("," + ea.getItemName());
                }
            }
            String itemNameStr = (itemNames.length() > 0) ? itemNames.substring(1) : "";
            ExamApplyDto ea2 = new ExamApplyDto();
            ea2.setMergeNo(mergeNos);
            ea2.setApplyNo(applyno);
            ea2.setTerminalType("D");
            ea2.setSignInLimit("0");
            ea2.setHospitalCode(hospitalCode);
            JsonResult jsonResult = examApplyService.signinSchedule(ea2);
            ExamApplyDto eaSign = new ExamApplyDto();
            if (jsonResult.getStatus().equals("0") && "成功".equals(jsonResult.getMessage())) {
                ExamApplyDto result = (ExamApplyDto) jsonResult.getResult();
                eaSign.setIsSign("1");
                eaSign.setQueueNo(result.getQueueNo());
                eaSign.setItemNameStr(itemNameStr);
            } else {
                eaSign.setIsSign("0");
                eaSign.setItemNameStr(itemNameStr);
                eaSign.setScheduleDate(scheduleDate);
                eaSign.setScheduleApm(scheduleApm);
            }
            isSignInItem.add(eaSign);
        }
        return JsonResultUtil.success("成功", isSignInItem);
    }

    @Override
    public JsonResult signInScheduledItem(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getCommonCard())) {
            return JsonResultUtil.failure("综合号码不能为空");
        }
        List<String> sickIds = commonServiceImpl.getSickIds(dto);
        if (sickIds.size() == 0 || sickIds.size() > 1) {
            return JsonResultUtil.failure("您没有当天可报到的检查申请单请确认您的患者信息");
        }
        dto.setSickId(sickIds.get(0));
        List<ExamApplyDto> list = baseMapper.getSignInItem(dto);
        Map<String, ExamApplyDto> map = new HashMap<>();
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        for (ExamApplyDto ea : list) {
            String timeEarliest = StringUtils.isBlank(ea.getTimeEarliest()) ? "00:00:00" : ea.getTimeEarliest();
            String daysEarliest = StringUtils.isBlank(ea.getDaysEarliest()) ? "0" : ea.getDaysEarliest();
            String dateEarliest = DateUtil.addDays2(ea.getScheduledDate(), -Integer.parseInt(daysEarliest));
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String isSignIn = "1";
            try {
                Date date = format.parse(dateEarliest + " " + timeEarliest);
                Date date2 = format.parse(DateUtil.getCurrDateStr() + " " + DateUtil.getCurrentTime());
                if (date2.compareTo(date) < 0) {
                    isSignIn = "0";
                }
                Date date3 = format.parse(ea.getScheduledDate() + " " + ea.getTimeSignin());
                if (date3.compareTo(date2) < 0) {
                    isSignIn = "0";
                }
                ExamApplyDto e = map.get(ea.getScheduledId());
                if (e == null) {
                    ExamApplyDto eaDto = new ExamApplyDto();
                    eaDto.setApplyNo(ea.getApplyNo());
                    eaDto.setSickId(ea.getSickId());
                    eaDto.setScheduledId(ea.getScheduledId());
                    String scheduledDate = ea.getScheduledDate();
                    String scheduledApm = ea.getScheduleApm();
                    if ("0".equals(isSignIn)) {
                        Date date4 = df.parse(ea.getTimeEnd());
                        date4.setTime(date4.getTime() + 1000L);
                        String timeEnd = df.format(date4);
                        scheduledDate = dateEarliest;
                        scheduledApm = timeEarliest.substring(0, timeEarliest.length() - 3) + "~"
                                + timeEnd.substring(0, timeEnd.length() - 3);
                    }
                    eaDto.setScheduleDate(scheduledDate);
                    eaDto.setScheduleApm(scheduledApm);
                    eaDto.setItemNameStr(ea.getItemName());
                    eaDto.setMergeNo(ea.getApplyNo() + "-" + ea.getItemNo());
                    eaDto.setIsSign(isSignIn);
                    map.put(ea.getScheduledId(), eaDto);
                } else {
                    if (!ea.getScheduledId().equals(e.getScheduledId())) {
                        continue;
                    }
                    ExamApplyDto e2 = map.get(ea.getScheduledId());
                    e2.setItemNameStr(e2.getItemNameStr() + "," + ea.getItemName());
                    e2.setMergeNo(e2.getMergeNo() + "," + ea.getApplyNo() + "-" + ea.getItemNo());
                    map.put(ea.getScheduledId(), e2);
                }
            } catch (ParseException e3) {
                e3.printStackTrace();
            }
        }
        List<ExamApplyDto> isSignInItem = new ArrayList<ExamApplyDto>();
        for (String key : map.keySet()) {
            isSignInItem.add(map.get(key));
        }
        if (isSignInItem.size() == 0) {
            return JsonResultUtil.failure("您没有当天可报到的检查申请单请确认您的预约信息");
        }
        return JsonResultUtil.success("成功", isSignInItem);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult noRegularSchedule(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo()) && StringUtils.isBlank(dto.getItemCode())) {
            return JsonResultUtil.failure("申请单号不能为空");
        }
        if (StringUtils.isBlank(dto.getHospitalCode())) {
            return JsonResultUtil.failure("预约院区不能为空");
        }
        if (StringUtils.isBlank(dto.getScheduleDate())) {
            return JsonResultUtil.failure("预约日期不能为空");
        }
        if (StringUtils.isBlank(dto.getScheduleApm())) {
            return JsonResultUtil.failure("预约时段不能为空");
        }
        if (StringUtils.isBlank(dto.getQueueName())) {
            return JsonResultUtil.failure("检查队列不能为空");
        }
        if (StringUtils.isBlank(dto.getExamClass())) {
            return JsonResultUtil.failure("检查类别不能为空");
        }
        if (StringUtils.isBlank(dto.getApmCode())) {
            return JsonResultUtil.failure("时段编号不能为空");
        }
        String mergeNos = dto.getMergeNo();
        String[] mergeNoArr = mergeNos.split(",");
        if (mergeNoArr.length > 1) {
            ExamApplyDto delEa = new ExamApplyDto();
            delEa.setApplyNo(dto.getApplyNo());
            delEa.setMergeNo(dto.getMergeNo());
            delEa.setHospitalCode(dto.getHospitalCode());
            delEa.setTerminalType(dto.getTerminalType());
            delEa.setNewScheduleDate(dto.getScheduleDate());
            delEa.setNewScheduleApm(dto.getScheduleApm());
            delApm(delEa);
        }
        ExamApplyDto ea = new ExamApplyDto();
        if (StringUtils.isNotBlank(dto.getPhoneNumber())) {
            ea.setPhoneNumber(dto.getPhoneNumber());
        }
        dto.setSort("1");
        String isCompliance = commonServiceImpl.mergeRuleForScheduleJudge(ea, dto);
        if (StringUtils.isNotBlank(isCompliance)) {
            return JsonResultUtil.failure(isCompliance);
        }
        String applyNo = StringUtils.isBlank(dto.getApplyNo()) ? ea.getApplyNo() : dto.getApplyNo();
        DictUsersDto user = commonServiceImpl.dictUsers(dto);
        if ("08".equals(ea.getScheduleStatus())) {
            ExamApplyDto ex = new ExamApplyDto();
            ex.setTerminalType("A");
            ex.setExamClass(dto.getExamClass());
            ex.setUserId(user.getUserId());
            ex.setPassword(dto.getPassword());
            boolean checkPassword = configServiceImpl.isNeedPassWordByDeptsche(ex);
            if (!checkPassword) {
                return JsonResultUtil.failure("密码错误");
            }
        }
        if (!applyNo.startsWith("RE")) {
            ea.setMergeNo(mergeNos);
        }
        String chargeFlag = dto.getChargeFlag();
        if (!applyNo.startsWith("RE")
                && !ConstantsUtil.ScheduleStatus.EIGHT.getStatus().equals(ea.getScheduleStatus())) {
            JsonResult confirmFeeBeforeScheduleResult = commonServiceImpl.confirmFeeBeforeSchedule(ea,
                    ConstantsUtil.ActType.NO_REGULAR.getType(), user);
            if (confirmFeeBeforeScheduleResult != null && !"0".equals(confirmFeeBeforeScheduleResult.getStatus())) {
                String scheduleStatusByConfirmFee = configServiceImpl
                        .getConfigByName(ConstantsUtil.ConfigName.SCHEDULE_STATUS_BY_CONFIRM_FEE.getKey());
                if (StringUtils.isNotBlank(scheduleStatusByConfirmFee) && "1".equals(scheduleStatusByConfirmFee)) {
                    dto.setActDescription("确费失败,该申请单[" + dto.getMergeNo() + "]回退到未预约状态");
                    delApm(dto);
                } else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }
                return JsonResultUtil.failure(confirmFeeBeforeScheduleResult.getMessage());
            }
            boolean isNotUpdateChargeFlagByConfirmFee = configServiceImpl
                    .isOpenConfig(ConstantsUtil.ConfigName.IS_NOT_UPDATE_CHARGE_FLAG_BY_CONFIRM_FEE.getKey());
            if (confirmFeeBeforeScheduleResult != null && "0".equals(confirmFeeBeforeScheduleResult.getStatus())
                    && !isNotUpdateChargeFlagByConfirmFee) {
                ExamApplyDto up = new ExamApplyDto();
                up.setApplyNos(CommonUtil.split2List(applyNo));
                if (StringUtils.isNotBlank(mergeNos)) {
                    up.setApplyNos(CommonUtil.mergeNo2ApplyNos(mergeNos));
                }
                up.setChargeFlag("1");
                baseMapper.updateExamApply(up);
            }
            chargeFlag = commonServiceImpl.getChargeFlag(ea);
            ea.setTerminalType(dto.getTerminalType());
            boolean isChargeFirst = false;
            if (isChargeFirst && "0".equals(chargeFlag)) {
                return JsonResultUtil.failure("您的检查申请未缴费，不能预约。如有疑问请到护士站咨询!");
            }
            if (isChargeFirst && "2".equals(chargeFlag)) {
                return JsonResultUtil.failure("您的检查申请已作废或已退费，不能预约。如有疑问请到护士站咨询!");
            }
        }
        boolean isExamClass40rgan = configServiceImpl.getOrganExamClassList().contains(ea.getExamClass());
        Double reqCount = 1.0;
        if (isExamClass40rgan) {
            boolean isOrgansFlag = false;
            if (StringUtils.isNotBlank(ea.getScheduledId())) {
                reqCount = commonServiceImpl.getOrgansReqCount(ea);
                if (reqCount != null) {
                    isOrgansFlag = true;
                }
            }
            if (!isOrgansFlag) {
                reqCount = commonServiceImpl.getReqOrganByItems(ea.getItems());
            }
        }
        ExamApplyDto updateApm = null;
        String smsType = ConstantsUtil.SmsType.SCHEDULE.getType();
        String actType = ConstantsUtil.ActType.CONFIRM.getType();
        if (StringUtils.isNotBlank(ea.getScheduledId())) {
            actType = ConstantsUtil.ActType.UPDATE.getType();
            ExamApplyDto eaDto = new ExamApplyDto();
            eaDto.setOrgans(ea.getOrgans());
            eaDto.setApplyNo(ea.getApplyNo());
            eaDto.setScheduledId(ea.getScheduledId());
            eaDto.setNextApmRatio(ea.getNextApmRatio());
            eaDto.setScheduleDate(ea.getScheduleDate());
            eaDto.setMergeNo(mergeNos);
            eaDto.setReqCount((double) reqCount);
            eaDto.setRegularIdList(ea.getRegularIdList());
            eaDto.setApmCode(ea.getApmCode());
            if ("08".equals(ea.getScheduleStatus())) {
                eaDto.setExamClass(ea.getExamClass());
                eaDto.setTerminalType(dto.getTerminalType());
                smsType = ConstantsUtil.SmsType.UPDATE.getType();
            }
            eaDto.setType(ConstantsUtil.ActType.UPDATE.getType());
            commonServiceImpl.cancelScheduleInfo(eaDto, isExamClass40rgan);
            updateApm = eaDto.getUpdateApm();
            eaDto.setActType(ConstantsUtil.ActType.CANCEL.getType());
            eaDto.setScheduleApm(ea.getScheduleApm());
            eaDto.setHospitalCode(ea.getHospitalCode());
            eaDto.setTerminalType(ea.getTerminalType());
            eaDto.setQueueName(ea.getQueueName());
            eaDto.setExamClass(ea.getExamClass());
            eaDto.setName(ea.getName());
            eaDto.setAge(ea.getAge());
            eaDto.setSickId(ea.getSickId());
            eaDto.setItems(ea.getItems());
            eaDto.setDesc("[改约时取消预约]");
            commonServiceImpl.addExamScheduleAct(eaDto, user);
            // 【启用住院患者的申请单在修改预约与取消预约时，给申请单病区所关联的科室的用户发送消息提醒(二级提示内容)】(1：关闭 0：启用)
            if (configServiceImpl.isDeptNotice(ea.getPatientSource())) {
                List<String> itemNameList = new ArrayList<>();
                for (ExamApplyItemDto item : ea.getItems()) {
                    itemNameList.add(item.getItemName());
                }
                DeptNoticeDto deptNoticeDto = new DeptNoticeDto();
                deptNoticeDto.setName(ea.getName());
                deptNoticeDto.setActType(ConstantsUtil.ActType.UPDATE.getType());
                deptNoticeDto.setExamClass(ea.getExamClass());
                deptNoticeDto.setApplyNo(ea.getApplyNo());
                deptNoticeDto.setScheduledDate(dto.getScheduleDate());
                deptNoticeDto.setScheduleApm(dto.getScheduleApm());
                deptNoticeDto.setOldScheduleDate(ea.getScheduleDate());
                deptNoticeDto.setOldScheduleApm(ea.getScheduleApm());
                deptNoticeDto.setItemName(String.join(";", itemNameList));
                deptNoticeDto.setApplyNos(ea.getApplyNos());
                deptNoticeDto.setAge(ea.getAge());
                deptNoticeDto.setSex(ea.getSex());
                deptNoticeDto.setDeptName(ea.getPerformDeptName());
                deptNoticeDto.setReqDept(ea.getReqDept());
                deptNoticeDto.setReqWardCode(ea.getReqWardCode());
                deptNoticeService.saveDeptNotice(deptNoticeDto, user);
            }
        }
        ExamSchedule es = new ExamSchedule();
        String scheduledId = PKGeneratorSingle.getInstance().nextPKStr();
        List<String> notices = new ArrayList<String>();
        for (ExamApplyItemDto item2 : ea.getItems()) {
            if (StringUtils.isNotBlank(item2.getNotice())) {
                notices.add(item2.getNotice());
            }
            ExamScheduleItem examScheduleItem = new ExamScheduleItem();
            examScheduleItem.setApplyNo(item2.getApplyNo());
            examScheduleItem.setItemNo(item2.getItemNo());
            examScheduleItem.setScheduledId(scheduledId);
            examScheduleItem.setItemName(item2.getItemName());
            examScheduleItemMapper.insert(examScheduleItem);
        }
        DictScheduleApm d = dictScheduleApmService.selectOneByApmCode(dto.getApmCode());
        DictScheduleApmDto dsa = new DictScheduleApmDto();
        BeanUtils.copyProperties(d, dsa);
        ea.setIsExamClass4Organ(isExamClass40rgan);
        ea.setIsGreenChannel("1");
        ruleEngineServiceImpl.quantityRuleJudge(ea, dsa, dto.getScheduleDate());
        String sb = commonServiceImpl.getRegularId(ea.getRegularIdList(), isExamClass40rgan);
        List<String> regularIdList = ea.getRegularIdList();
        if (StringUtils.isNotBlank(sb)) {
            es.setRegularId(sb);
        }
        es.setScheduledId(scheduledId);
        es.setApmCode(dto.getApmCode());
        es.setScheduledDate(dto.getScheduleDate());
        es.setScheduleApm(dto.getScheduleApm());
        es.setQueueName(dto.getQueueName());
        es.setScheduledTime(commonServiceImpl.getScheduleTime(es, ""));
        es.setHospitalCode(dto.getHospitalCode());
        es.setScheduler(user.getName());
        es.setScheduleStatus("08");
        es.setSchePath(ConstantsUtil.TerminalTypeSchePath.NO_REGULAR.key);
        if (isExamClass40rgan) {
            es.setOrgans(reqCount);
        }
        String queueNoClass = configServiceImpl
                .getConfigByName(ConstantsUtil.ConfigName.NO_REGULAR_QUEUE_NO_CLASS.getKey());
        if (StringUtils.isNotBlank(queueNoClass) && queueNoClass.contains(ea.getExamClass())) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("queueDate", dto.getScheduleDate());
            map.put("queueName", dto.getQueueName());
            map.put("queueApm", dto.getScheduleApm());
            map.put("queueClass", ea.getPriorityOrder());
            String queueNo = examScheduleMapper.getScheduleQueueNo(map);
            es.setQueueNo(queueNo);
        }
        String queueClass = (ea.getPriorityOrder() != null) ? ea.getPriorityOrder() : "普通";
        es.setQueueClass(queueClass);
        boolean bool = examScheduleMapper.insert(es) > 0;
        commonServiceImpl.addExamScheduleApmRegular(isExamClass40rgan, regularIdList, dto.getScheduleDate(), true);
        String process = "";
        if (bool) {
            ExamScheduleApm esaQw = new ExamScheduleApm();
            esaQw.setApmCode(dto.getApmCode());
            esaQw.setScheduleDate(dto.getScheduleDate());
            ExamScheduleApm esa = examScheduleApmService.getExamScheduleApm(esaQw);
            DictScheduleApm apm = dictScheduleApmService.selectOneByApmCode(dto.getApmCode());
            if (isExamClass40rgan) {
                if (esa != null) {
                    double organs = 0.0;
                    if (esa.getOrgans() != null) {
                        organs = esa.getOrgans();
                    }
                    int count = (esa.getCount() == null) ? 0 : esa.getCount();
                    ExamScheduleApm examScheduleApm = new ExamScheduleApm();
                    examScheduleApm.setOrgans(organs + reqCount);
                    examScheduleApm.setCount(count + 1);
                    examScheduleApm.setApmCode(dto.getApmCode());
                    examScheduleApm.setScheduleDate(dto.getScheduleDate());
                    double organsRecycle = (esa.getOrgansRecycle() == null) ? 0.0 : esa.getOrgansRecycle();
                    double organsTotal = organs + reqCount;
                    double organsTotals = BigDecimalUtil.add(organsTotal, organsRecycle);
                    boolean isPassMaxLimit = organsTotals > apm.getMaxLimit();
                    if (isPassMaxLimit) {
                        organsRecycle = BigDecimalUtil.subtract(apm.getMaxLimit(), organsTotal);
                        if (organsRecycle < 0.0) {
                            organsRecycle = 0.0;
                        }
                        examScheduleApm.setOrgansRecycle(organsRecycle);
                    }
                    process = organs + "->" + organsTotal;
                    examScheduleApmService.updateExamScheduleApm(examScheduleApm);
                } else {
                    ExamScheduleApm examScheduleApm2 = new ExamScheduleApm();
                    examScheduleApm2.setScheduleDate(dto.getScheduleDate());
                    examScheduleApm2.setApmCode(dto.getApmCode());
                    examScheduleApm2.setOrgans(reqCount);
                    examScheduleApm2.setCount(1);
                    examScheduleApmMapper.insert(examScheduleApm2);
                    process = "0->" + reqCount;
                }
            } else if (esa != null) {
                ExamScheduleApm examScheduleApm2 = new ExamScheduleApm();
                examScheduleApm2.setCount(esa.getCount() + 1);
                examScheduleApm2.setApmCode(dto.getApmCode());
                examScheduleApm2.setScheduleDate(dto.getScheduleDate());
                int countRecycle = (esa.getCountRecycle() == null) ? 0 : esa.getCountRecycle();
                int count = esa.getCount() + 1;
                Double countTotal = BigDecimalUtil.add(count, countRecycle);
                boolean isPassMaxLimit2 = countTotal > apm.getMaxLimit();
                if (isPassMaxLimit2) {
                    countRecycle = apm.getMaxLimit().intValue() - count;
                    examScheduleApm2.setCountRecycle(countRecycle);
                }
                examScheduleApmService.updateExamScheduleApm(examScheduleApm2);
            } else {
                ExamScheduleApm examScheduleApm2 = new ExamScheduleApm();
                examScheduleApm2.setScheduleDate(dto.getScheduleDate());
                examScheduleApm2.setApmCode(dto.getApmCode());
                examScheduleApm2.setCount(1);
                examScheduleApmMapper.insert(examScheduleApm2);
            }
        }
        DictExamQueueDto queueDto = new DictExamQueueDto();
        queueDto.setQueueName(dto.getQueueName());
        DictExamQueueDto deqd = dictExamQueueMapper.getPerformDeptByQueueName(queueDto);
        if (bool && StringUtils.isBlank(dto.getItemCode())) {
            UpdateWrapper<ExamApply> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("APPLY_NO", CommonUtil.mergeNo2ApplyNos(dto.getMergeNo()));
            ExamApply examApply = new ExamApply();
            examApply.setPerformDept(deqd.getDeptCode());
            examApply.setPerformDeptName(deqd.getDeptName());
            examApply.setExamClass(dto.getExamClass());
            baseMapper.update(examApply, updateWrapper);
        }
        if (StringUtils.isNotBlank(dto.getItemCode())) {
            ea.setScheduleStatus("08");
            dto.setApplyNo(ea.getApplyNo());
            dto.setMergeNo(ea.getMergeNo());
            commonServiceImpl.saveRefer(ea, dto.getQueueName());
        }
        if (!bool) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return JsonResultUtil.failure("预约失败");
        }
        ea.setTerminalType(dto.getTerminalType());
        ea.setScheduleDate(dto.getScheduleDate());
        ea.setScheduleApm(dto.getScheduleApm());
        ea.setQueueName(dto.getQueueName());
        ea.setHospitalCode(dto.getHospitalCode());
        ea.setScheduledId(scheduledId);
        ea.setActType(ConstantsUtil.ActType.NO_REGULAR.getType());
        String nextOrganProcess = "";
        if (StringUtils.isNotBlank(ea.getProcess())) {
            process = ea.getProcess() + "|" + process;
            if (StringUtils.isNotBlank(ea.getNextOrganProcess())) {
                nextOrganProcess = ea.getNextOrganProcess() + "|" + nextOrganProcess;
            }
        }
        ea.setProcess(process);
        ea.setNextOrganProcess(nextOrganProcess);
        commonServiceImpl.addExamScheduleAct(ea, user);
        ea.setQueueName(dto.getQueueName());
        ea.setApmCode(dto.getApmCode());
        DictScheduleApm apm2 = dictScheduleApmService.selectOneByApmCode(dto.getApmCode());
        String endTime = DateUtil.addSecond(apm2.getTimeEnd(), 1);
        endTime = endTime.substring(0, apm2.getTimeEnd().length() - 3);
        String startTime = apm2.getTimeStart().substring(0, apm2.getTimeStart().length() - 3);
        List<Map<String, String>> convertSms = CommonUtil.convertSms(notices, dto.getScheduleDate(), startTime,
                endTime);
        if (CollectionUtils.isNotEmpty(convertSms)) {
            commonServiceImpl.addSmsByItemNotice(ea, convertSms, dto);
        }
        commonServiceImpl.addExamSmsNotice(ea, smsType, dto);
        Boolean isGetQueueNoFirst = configServiceImpl.isGetQueueNoFirst(ea.getPatientSource(), ea.getQueueName());
        ExamApplyDto examApplyDto = new ExamApplyDto();
        BeanUtils.copyProperties(ea, examApplyDto);
        examApplyDto.setScheduledId(ea.getScheduledId());
        examApplyDto.setApplyNo(ea.getApplyNo());
        examApplyDto.setChargeFlag(chargeFlag);
        examApplyDto.setScheduleStatus("2");
        String m = ea.getMergeNo();
        DictScheduleApmDto scheduleApm = commonServiceImpl.getTimeEarliest(dto.getApmCode());
        String timeEarliest = scheduleApm.getTimeEarliest();
        String timeSignin = scheduleApm.getTimeSignin();
        examApplyDto.setScheduleDate(dto.getScheduleDate());
        examApplyDto.setTimeEarliest(timeEarliest);
        examApplyDto.setTimeSignin(timeSignin);
        examApplyDto.setIsGetQueueNoFirst(isGetQueueNoFirst);
        if (isGetQueueNoFirst) {
            examApplyDto.setIsPrint(configServiceImpl.isPrint4Sign(ea) ? "1" : "0");
            examApplyDto.setIsRemindPrint(configServiceImpl.isRemindPrint4Sign(ea) ? "1" : "0");
        } else {
            examApplyDto.setIsPrint(configServiceImpl.isPrint4Schedule(ea) ? "1" : "0");
            examApplyDto.setIsRemindPrint(configServiceImpl.isRemindPrint4Schedule(ea) ? "1" : "0");
            String isSign = configServiceImpl.isScheduleTodayBySign(examApplyDto, scheduleApm) ? "1" : "0";
            examApplyDto.setIsSign(isSign);
            examApplyDto.setIsPrintCode(configServiceImpl.isPrintCode4Schedule(ea) ? "1" : "0");
        }
        if (updateApm != null) {
            commonServiceImpl.cancelScheduleApm(updateApm);
        }
        examApplyDto.setActType(actType);
        return JsonResultUtil.success("成功", examApplyDto);
    }

    /**
     * 构建打印预约凭条的内容
     *
     * @param dto
     * @return
     */
    @Override
    public JsonResult print(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo())) {
            return JsonResultUtil.failure("申请单号不能为空");
        }
        if (StringUtils.isBlank(dto.getTerminalType())) {
            return JsonResultUtil.failure("终端类型不能为空");
        }
        List<ExamApplyDto> applies = new ArrayList<>();
        Set<String> set = new HashSet<>();
        Map<String, String> megerNoMap = new HashMap<>();
        ExamApplyDto eaDto = new ExamApplyDto();
        List<String> reqMemos = new ArrayList<>();
        Set<String> flags = new HashSet<>();
        if (dto.getApplyNo().startsWith("RE")) {
            applies.add(examReferMapper.getExamRefers(dto).get(0));
        } else if (StringUtils.isNotBlank(dto.getMergeNo())) {
            String[] split = dto.getMergeNo().split(",");
            for (String s : split) {
                eaDto.setApplyNo(s.substring(0, s.lastIndexOf("-")));
                eaDto.setItemNo(Long.valueOf(s.substring(s.lastIndexOf("-") + 1)));
                List<ExamApplyDto> examApplyDtos = baseMapper.findByApplyNo(eaDto);
                if (examApplyDtos.isEmpty()) {
                    return JsonResultUtil.failure("打印失败请重试");
                }
                ExamApplyDto examApplyDto = examApplyDtos.get(0);
                if (set.add(examApplyDto.getExamNo())) {
                    applies.add(examApplyDto);
                    megerNoMap.put(examApplyDto.getExamNo(), s);
                } else {
                    String megerNo = megerNoMap.get(examApplyDto.getExamNo());
                    megerNoMap.put(examApplyDto.getExamNo(), megerNo + "," + s);
                }
                if (!reqMemos.contains(examApplyDto.getReqMemo())) {
                    reqMemos.add(examApplyDto.getReqMemo());
                }
                if (StringUtils.isNotBlank(examApplyDto.getFlags())) {
                    flags.add(examApplyDto.getFlags());
                }
            }
        } else {
            eaDto.setApplyNo(dto.getApplyNo());
            ExamApplyDto examApplyDto2 = baseMapper.findByApplyNo(eaDto).get(0);
            if (examApplyDto2 != null && set.add(examApplyDto2.getExamNo())) {
                applies.add(examApplyDto2);
            }
        }
        if (applies.size() < 1) {
            String strReturn = "您的检查申请单信息不存在，如有疑问请到护士站咨询";
            String reminder = configServiceImpl
                    .customReminder(ConstantsUtil.ConfigName.NO_QUERY_EXAM_APPLY_REMINDER.getKey(), "", "");
            if (StringUtils.isNotBlank(reminder)) {
                strReturn = reminder;
            }
            return JsonResultUtil.failure(strReturn);
        }
        ExamApplyDto ea = applies.get(0);
        ea.setReqMemo(StringUtils.join(reqMemos, ","));
        ea.setFlags(StringUtils.join(flags, ","));
        logger.info("{}检查状态:{}", ea.getApplyNo(), ea.getExamStatus());
        logger.info("{}预约状态:{}", ea.getApplyNo(), ea.getScheduleStatus());
        String actType = "";
        if (StringUtils.isBlank(dto.getPatternType())) {
            if (StringUtils.isBlank(ea.getExamStatus())
                    && ConstantsUtil.ScheduleStatus.EIGHT.getStatus().equals(ea.getScheduleStatus())) {
                dto.setPatternType("0");
                actType = ConstantsUtil.ActType.SCHE_PRINT.getType();
            } else {
                if (!"10,20,40,50".contains(ea.getExamStatus())) {
                    logger.info("@{}@,预约状态:{}", ea.getApplyNo(),
                            (StringUtils.isNotBlank(ea.getExamStatus()) ? ea.getExamStatus() : ea.getScheduleStatus()));
                    return JsonResultUtil.failure("没有预约申请或已检查！");
                }
                dto.setPatternType("1");
                actType = ConstantsUtil.ActType.SIGN_PRINT.getType();
            }
        }
        String examClass = ea.getExamClass();
        String patientsource = ea.getPatientSource();
        String queueName = ea.getQueueName();
        String terminalType = dto.getTerminalType();
        DictPrintPatternDto printPatternDto = new DictPrintPatternDto();
        printPatternDto.setPatternType(dto.getPatternType());
        printPatternDto.setExamClass(examClass);
        printPatternDto.setTerminalType(terminalType);
        List<DictPrintPatternDto> printConfigs = printPatternService.getPatternList(printPatternDto);
        if (printConfigs.isEmpty()) {
            return JsonResultUtil.failure("未查询到凭条模板,请添加模板后重试!");
        }
        printConfigs.removeIf(schedulePrint -> StringUtils.isNotBlank(schedulePrint.getQueueName())
                && !schedulePrint.getQueueName().contains(queueName));
        int level = 0;
        String patternContent = "";
        String width = "";
        String height = "";
        for (DictPrintPatternDto printConfig : printConfigs) {
            boolean isExamClass = ((printConfig.getExamClass() != null) ? printConfig.getExamClass() : "")
                    .equals(examClass);
            boolean isPatientSource = ((printConfig.getPatientSource() != null) ? printConfig.getPatientSource() : "")
                    .contains(patientsource);
            boolean isQueueName = ((printConfig.getQueueName() != null) ? ("," + printConfig.getQueueName() + ",") : "")
                    .contains("," + queueName + ",");
            boolean isTerminalType = ((printConfig.getTerminalType() != null)
                    ? ("," + printConfig.getTerminalType() + ",")
                    : "").contains("," + terminalType + ",");
            if (level < 1 && isExamClass && isTerminalType && !isQueueName && !isPatientSource) {
                patternContent = printConfig.getPatternContent();
                width = printConfig.getWidth();
                height = printConfig.getHeight();
                level = 1;
            }
            if (level < 2 && isExamClass && !isQueueName && isTerminalType && isPatientSource) {
                patternContent = printConfig.getPatternContent();
                width = printConfig.getWidth();
                height = printConfig.getHeight();
                level = 2;
            } else if (level < 3 && isExamClass && !isPatientSource && isTerminalType && isQueueName) {
                patternContent = printConfig.getPatternContent();
                width = printConfig.getWidth();
                height = printConfig.getHeight();
                level = 3;
            } else {
                if (level < 4 && isExamClass && isQueueName && isPatientSource && isTerminalType) {
                    patternContent = printConfig.getPatternContent();
                    width = printConfig.getWidth();
                    height = printConfig.getHeight();
                    level = 4;
                    break;
                }
            }
        }
        String content = "";
        String no = ea.getSickId();
        if ("1".equals(dto.getPatternType())) {
            no = ea.getExamNo();
        }
        ExamApplyPatientIdDto examApplyPatientId = new ExamApplyPatientIdDto();
        examApplyPatientId.setSickId(ea.getSickId());
        examApplyPatientId.setDomainId("0007");
        List<ExamApplyPatientId> ids = idService.selectd(examApplyPatientId);
        String icCard = ea.getIcCard();
        if (!ids.isEmpty()) {
            icCard = (StringUtils.isNotBlank(ids.get(0).getPatientId()) ? ids.get(0).getPatientId() : ea.getIcCard());
        }
        String PrintByExamNo = configServiceImpl.getConfigByName(ConstantsUtil.ConfigName.PRINT_BY_EXAM_NO.getKey());
        boolean isExamNos = ((PrintByExamNo != null) ? PrintByExamNo : "").contains(ea.getExamClass());
        if (isExamNos && applies.size() > 1) {
            for (ExamApplyDto applyDto : applies) {
                HashMap<String, Object> map = new HashMap<String, Object>();
                dto.setApplyNo(applyDto.getApplyNo());
                dto.setMergeNo(megerNoMap.get(applyDto.getExamNo()));
                map.put("CODE_CARD", icCard);
                commonServiceImpl.converPatternMap(applyDto, map, dto, null);
                String barCode = "data:image/png;base64," + EncoderUtil.barcode(applyDto.getExamNo(), 210, 50);
                map.put("BAR_CODE", barCode);
                String qrCode = "data:image/png;base64," + QrCodeUtil.creatRrCode(ea.getApplyNo(), 150, 150);
                map.put("QR_CODE", qrCode);
                String cloudFilmUrl_tmp = configServiceImpl
                        .getConfigByName(ConstantsUtil.ConfigName.CLOUD_FILM_URL.getKey());
                if (StringUtils.isNotBlank(cloudFilmUrl_tmp)) {
                    String cloudFilmUrl = CommonUtil.replaceMsg(cloudFilmUrl_tmp, map);
                    String cloudFilmUrlCode = "data:image/png;base64," + QrCodeUtil.creatRrCode(cloudFilmUrl, 150, 150);
                    map.put("CLOUD_FILM_URL", cloudFilmUrlCode);
                }
                if (StringUtils.isNotBlank(ea.getIcCard())) {
                    String qrCode_icCard = "data:image/png;base64," + QrCodeUtil.creatRrCode(icCard, 150, 150);
                    map.put("QR_CODE_ICCARD", qrCode_icCard);
                }
                if (StringUtils.isNotBlank(ea.getInpatientNo())) {
                    String qrCode_inpatientNo = "data:image/png;base64," + QrCodeUtil
                            .creatRrCode((ea.getInpatientNo() != null) ? ea.getInpatientNo() : "", 150, 150);
                    map.put("QR_CODE_INPATIENTNO", qrCode_inpatientNo);
                }
                if (StringUtils.isNotBlank(ea.getOutpatientNo())) {
                    String qrCode_outpatientNo = "data:image/png;base64," + QrCodeUtil
                            .creatRrCode((ea.getOutpatientNo() != null) ? ea.getOutpatientNo() : "", 150, 150);
                    map.put("QR_CODE_OUTPATIENTNO", qrCode_outpatientNo);
                }
                if (configServiceImpl.getPatientSourceIn().equals(ea.getPatientSource())) {
                    String qrCode_inpatNo = "data:image/png;base64," + QrCodeUtil
                            .creatRrCode((ea.getInpatientNo() != null) ? ea.getInpatientNo() : "", 150, 150);
                    map.put("QR_CODE_INPATNO_CARD", qrCode_inpatNo);
                } else {
                    String qrCode_icCard = "data:image/png;base64,"
                            + QrCodeUtil.creatRrCode((icCard != null) ? icCard : "", 150, 150);
                    map.put("QR_CODE_INPATNO_CARD", qrCode_icCard);
                }
                if (StringUtils.isNotBlank(applyDto.getImgNo())) {
                    // 二维码
                    String qrCodeImgNO = "data:image/png;base64,"
                            + QrCodeUtil.creatRrCode(applyDto.getImgNo(), 150, 150);
                    map.put("QR_CODE_IMG_NO", qrCodeImgNO);
                    // 条码
                    String brCodeImgNO = "data:image/png;base64," + EncoderUtil.barcode(applyDto.getImgNo(), 105, 50);
                    map.put("BR_CODE_IMG_NO", brCodeImgNO);
                }
                content = content + "</br></br>" + CommonUtil.replaceMsg(patternContent, map);
            }
            content = content.substring(10);
        } else {
            HashMap<String, Object> map2 = new HashMap<>();
            map2.put("CODE_CARD", icCard);
            commonServiceImpl.converPatternMap(ea, map2, dto, null);
            String barCode2 = "data:image/png;base64," + EncoderUtil.barcode(no, 210, 50);
            map2.put("BAR_CODE", barCode2);
            String qrCode2 = "data:image/png;base64," + QrCodeUtil.creatRrCode(ea.getApplyNo(), 100, 100);
            map2.put("QR_CODE", qrCode2);
            String cloudFilmUrl_tmp2 = configServiceImpl
                    .getConfigByName(ConstantsUtil.ConfigName.CLOUD_FILM_URL.getKey());
            if (StringUtils.isNotBlank(cloudFilmUrl_tmp2)) {
                String cloudFilmUrl2 = CommonUtil.replaceMsg(cloudFilmUrl_tmp2, map2);
                String cloudFilmUrlCode2 = "data:image/png;base64," + QrCodeUtil.creatRrCode(cloudFilmUrl2, 150, 150);
                map2.put("CLOUD_FILM_URL", cloudFilmUrlCode2);
            }
            if (StringUtils.isNotBlank(ea.getIcCard())) {
                String qrCode_icCard2 = "data:image/png;base64," + QrCodeUtil.creatRrCode(icCard, 150, 150);
                map2.put("QR_CODE_ICCARD", qrCode_icCard2);
            }
            if (StringUtils.isNotBlank(ea.getInpatientNo())) {
                String qrCode_inpatientNo2 = "data:image/png;base64,"
                        + QrCodeUtil.creatRrCode((ea.getInpatientNo() != null) ? ea.getInpatientNo() : "", 150, 150);
                map2.put("QR_CODE_INPATIENTNO", qrCode_inpatientNo2);
            }
            if (StringUtils.isNotBlank(ea.getOutpatientNo())) {
                String qrCode_outpatientNo2 = "data:image/png;base64,"
                        + QrCodeUtil.creatRrCode((ea.getOutpatientNo() != null) ? ea.getOutpatientNo() : "", 150, 150);
                map2.put("QR_CODE_OUTPATIENTNO", qrCode_outpatientNo2);
            }
            if (configServiceImpl.getPatientSourceIn().equals(ea.getPatientSource())) {
                String qrCode_inpatNo2 = "data:image/png;base64,"
                        + QrCodeUtil.creatRrCode((ea.getInpatientNo() != null) ? ea.getInpatientNo() : "", 150, 150);
                map2.put("QR_CODE_INPATNO_CARD", qrCode_inpatNo2);
            } else {
                String qrCode_icCard2 = "data:image/png;base64,"
                        + QrCodeUtil.creatRrCode((icCard != null) ? icCard : "", 150, 150);
                map2.put("QR_CODE_INPATNO_CARD", qrCode_icCard2);
            }
            if (StringUtils.isNotBlank(ea.getImgNo())) {
                // 二维码
                String qrCodeImgNO = "data:image/png;base64," + QrCodeUtil.creatRrCode(ea.getImgNo(), 150, 150);
                map2.put("QR_CODE_IMG_NO", qrCodeImgNO);
                // 条码
                String brCodeImgNO = "data:image/png;base64," + EncoderUtil.barcode(ea.getImgNo(), 105, 50);
                map2.put("BR_CODE_IMG_NO", brCodeImgNO);
            }
            content += CommonUtil.replaceMsg(patternContent, map2);
        }
        DictPrintPatternDto dictPrintPatternDto = new DictPrintPatternDto();
        dictPrintPatternDto.setPatternContent(content);
        dictPrintPatternDto.setBarCode(no);
        dictPrintPatternDto.setPatternHeight((height != null) ? height : "");
        dictPrintPatternDto.setPatternWidth((width != null) ? width : "");
        ExamSchedule es = new ExamSchedule();
        es.setScheduledId(ea.getScheduledId());
        int printCnt = (ea.getPrintCnt() != null) ? Integer.parseInt(ea.getPrintCnt()) : 0;
        es.setPrintCnt(printCnt + 1);
        examScheduleService.editExamScheduleById(es);
        if (StringUtils.isNotBlank(actType) && !Objects.equals(dto.getIsPreview(), "1")) {
            DictUsersDto obj = commonServiceImpl.dictUsers(dto);
            ea.setActType(actType);
            ea.setTerminalType(dto.getTerminalType());
            commonServiceImpl.addExamScheduleAct(ea, obj);
        }
        return JsonResultUtil.success("成功", dictPrintPatternDto);
    }

    @Override
    public JsonResult printMulti(List<ExamApplyDto> list) {
        List<String> queueNos = new ArrayList<String>();
        String message = "";
        if (Objects.equals(configServiceImpl.getConfigByName(ConstantsUtil.ConfigName.IS_AUTO_TRIAGE.getKey()), "0")) {
            List<String> applyNoList = list.stream().map(ExamApply::getApplyNo).collect(Collectors.toList());
            Map<String, String> map = new HashMap<String, String>();
            map.put("applyNo", "applyNo=" + String.join("|", applyNoList));
            map.put("queueNo", "");
            map.put("message", "");
            map.put("status", "");
            logger.info("@@@@@自动分诊参数:{}", ("applyNo=" + String.join("|", applyNoList)));
            baseMapper.autoTriage(map);
            logger.info("自动分诊过程返回:{}", JsonUtil.toJson(map));
            queueNos = new ArrayList<String>();
            message = "";
            if (Objects.equals(map.get("status"), "0")) {
                String[] arr = map.get("queueNo").split("\\|");
                queueNos = Arrays.asList(arr);
                message = map.get("message");
            }
        }
        List<String> items = new ArrayList<String>();
        DictPrintPatternDto patternDto = new DictPrintPatternDto();
        String patternContent = "";
        for (ExamApplyDto dto : list) {
            JsonResult jsonResult = print(dto);
            if (jsonResult != null && "0".equals(jsonResult.getStatus())) {
                String queueNo = "";
                if (!queueNos.isEmpty()) {
                    String applyQueue = queueNos.stream().filter(q -> q.contains(dto.getApplyNo())).findAny()
                            .orElse(" @ ");
                    queueNo = applyQueue.split("@")[1];
                }
                DictPrintPatternDto printPatternDto = (DictPrintPatternDto) jsonResult.getResult();
                String[] contentSplt = new String[0];
                if (StringUtils.isNotBlank(printPatternDto.getPatternContent())) {
                    contentSplt = printPatternDto.getPatternContent().split("\\&");
                }
                items.add(contentSplt[1].replace("#AUTO_TRIAGE_QUEUE_NO", queueNo));
                if (!StringUtils.isBlank(patternContent)) {
                    continue;
                }
                patternContent = contentSplt[0] + contentSplt[2];
                patternDto = printPatternDto;
            }
        }
        patternContent = patternContent.replace("#ITEM_LIST#", StringUtils.join(items, "<br>")).replace("#MESSAGE",
                message);
        patternDto.setPatternContent(patternContent);
        return JsonResultUtil.success("成功", patternDto);
    }

    public boolean delExamRefer(ExamApplyDto dto, boolean isExamClass4Organ) {
        commonServiceImpl.cancelScheduleInfo(dto, isExamClass4Organ);
        ExamRefer refer = new ExamRefer();
        refer.setApplyId(dto.getApplyNo());
        examReferService.delete(refer);
        ExamReferItem reItem = new ExamReferItem();
        reItem.setApplyId(dto.getApplyNo());
        examReferItemService.delete(reItem);
        return true;
    }

    /**
     * 删除申请单预约信息
     *
     * @param dto
     * @param isExamClass4Organ
     * @return
     */
    public boolean delExamSchedule(ExamApplyDto dto, boolean isExamClass4Organ) {
        ExamRefer refer = new ExamRefer();
        refer.setRealApplyNo(dto.getMergeNo());
        examReferService.delete(refer);
        // 删除申请单预约信息
        int n = commonServiceImpl.cancelScheduleInfo(dto, isExamClass4Organ);
        return n > 0;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult editLastMensesDate(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getIcCard())
                && StringUtils.isBlank(dto.getSickId())
                && StringUtils.isBlank(dto.getCommonCard())) {
            return JsonResultUtil.failure("卡号不能为空");
        }

        if (StringUtils.isBlank(dto.getSickId())
                && (StringUtils.isNotBlank(dto.getIcCard())
                || StringUtils.isNotBlank(dto.getCommonCard()))) {

            List<String> sickIds = commonServiceImpl.getSickIds(dto);
            if (sickIds.size() == 0) {
                return JsonResultUtil.failure("没有您的检查申请记录,如有疑问请到护士站咨询");
            }
            dto.setSickId(sickIds.get(0));
        }

        if (StringUtils.isBlank(dto.getLastMensesDate())
                && StringUtils.isBlank(dto.getGestationalWeeks())
                && StringUtils.isBlank(dto.getGestationalDays())) {
            return JsonResultUtil.failure("末次月经和怀孕周数不能同时为空");
        }

        boolean updateResult = true;
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        List<ExamApplyDto> examApplyList = baseMapper.getList(dto);
        if (examApplyList != null && !examApplyList.isEmpty()) {
            ExamApplyDto examApplyDto = examApplyList.get(0);
            // 最后生理日期
            String lastMensesDate = null;
            // 怀孕日期
            String pregnancyDate = null;

            if (StringUtils.isNotBlank(dto.getLastMensesDate())) {
                String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                int isBeforeToday = today.compareTo(dto.getLastMensesDate());
                if (isBeforeToday < 0) {
                    return JsonResultUtil.failure("请选择今天之前的日期");
                }
                lastMensesDate = dto.getLastMensesDate();
            }
            if (StringUtils.isBlank(lastMensesDate)) {
                int weekCount = (StringUtils.isBlank(dto.getGestationalWeeks()) ? 0
                        : Integer.parseInt(dto.getGestationalWeeks())) * 7;
                int dayCount = StringUtils.isBlank(dto.getGestationalDays()) ? 0
                        : Integer.parseInt(dto.getGestationalDays());
                lastMensesDate = LocalDate.now().minusDays(weekCount + dayCount).toString();
                if (StringUtils.isNotBlank(dto.getExamDate())) {
                    lastMensesDate = DateUtil.addDays2(dto.getExamDate(), -(weekCount + dayCount));
                    pregnancyDate = DateUtil.addDays2(dto.getExamDate(), -(weekCount + dayCount));
                }
            }
            /// String oldLastMensesDate =
            /// commonServiceImpl.getLastMensesDate(dto.getSickId());
            ExamApply examApply = new ExamApply();
            QueryWrapper<ExamApply> qw = new QueryWrapper();
            examApply.setLastMensesDate(lastMensesDate);
            if (pregnancyDate != null) {
                examApply.setPregnancyDate(pregnancyDate);
            }
            qw.eq("SICK_ID", dto.getSickId());
            updateResult = examApplyService.update(examApply, qw);

            ExamApplyPatient examPatient = new ExamApplyPatient();
            examPatient.setLastMensesDate(lastMensesDate);
            QueryWrapper<ExamApplyPatient> examPatientQw = new QueryWrapper();
            examPatientQw.eq("SICK_ID", dto.getSickId());
            if (examApplyPatientService.count(examPatientQw) > 0) {
                examApplyPatientService.update(examPatient, examPatientQw);
            } else {
                examPatient.setMotherSickId(examApplyDto.getMotherSickId());
                examPatient.setIcCard(examApplyDto.getIcCard());
                examPatient.setIdentityCard(examApplyDto.getIdentityCard());
                examPatient.setName(examApplyDto.getName());
                examPatient.setSex(examApplyDto.getSex());
                examPatient.setBirthDate(examApplyDto.getBirthDate());
                examPatient.setBirthTime(examApplyDto.getBirthTime());
                examPatient.setBirthPlace(examApplyDto.getBirthPlace());
                examPatient.setMailingAddress(examApplyDto.getMailingAddress());
                examPatient.setPhoneNumber(examApplyDto.getPhoneNumber());
                examPatient.setZipCode(examApplyDto.getZipCode());
                examPatient.setSickId(examApplyDto.getSickId());
                examApplyPatientService.save(examPatient);
            }
        }
        if (updateResult) {
            return JsonResultUtil.success("成功");
        }
        return JsonResultUtil.failure("失败");
    }

    private Map<String, String> getScheduled4Map(String applyNo, String examClass, String scheduleDate) {
        Map<String, String> map_scheduled = null;
        ExamScheduleDto dto = new ExamScheduleDto();
        dto.setApplyNo(applyNo);
        dto.setExamClass(examClass);
        dto.setScheduledDate(scheduleDate);
        List<String> queueNames = examScheduleMapper.getScheduledQueueNames((ExamSchedule) dto);
        if (queueNames != null && queueNames.size() > 0) {
            String key = examClass + "_" + scheduleDate;
            String value = "";
            map_scheduled = new HashMap<String, String>();
            for (String queueName : queueNames) {
                value = value + queueName + ",";
            }
            map_scheduled.put(key, value);
        }
        return map_scheduled;
    }

    /**
     * 患者是否再孕期
     *
     * @param dto
     * @return
     */
    @Override
    public JsonResult isGestation(ExamApplyDto dto) {
        List<String> sickIdList = new ArrayList<String>();
        // 将请求的参数转换成患者id列表
        if (StringUtils.isBlank(dto.getSickId()) && (StringUtils.isNotBlank(dto.getIcCard())
                || StringUtils.isNotBlank(dto.getCommonCard()))) {
            List<String> sickIds = commonServiceImpl.getSickIds(dto);
            if (CollectionUtils.isEmpty(sickIds)) {
                return JsonResultUtil.failure("没有您的检查申请记录,如有疑问请到护士站咨询");
            }
            dto.setIcCard(null);
            sickIdList = sickIds;
        } else {
            if (!StringUtils.isNotBlank(dto.getSickId())) {
                return JsonResultUtil.failure("sickId不能为空");
            }
            sickIdList = CommonUtil.split2List(dto.getSickId());
        }
        List<Map<String, Object>> resultList = new ArrayList<>();
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        for (String sickId : sickIdList) {
            dto.setSickId(sickId);
            String lastMensesDateStr = null;
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("sickId", sickId);
            // 是否孕期 0否 1是
            String isGestational = "0";

            // 获取患者申请单列表
            List<ExamApplyDto> examApplyList = baseMapper.getList(dto);
            if (CollectionUtils.isEmpty(examApplyList)) {
                return JsonResultUtil.failure("没有您的检查申请记录,如有疑问请到护士站咨询!");
            }
            // 移除超过检查时间的申请单
            examApplyList.removeIf(ea -> configServiceImpl.isApplyDateLimit(dto.getTerminalType(), ea.getExamClass(),
                    ea.getReqDate()));

            if (CollectionUtils.isEmpty(examApplyList)) {
                return JsonResultUtil.failure("没有您的检查申请记录,如有疑问请到护士站咨询!");
            }

            // 遍历出女性患者申请单列表
            List<ExamApplyDto> femaleApplyList = examApplyList.stream()
                    .filter(examApply -> StringUtils.isNotBlank(examApply.getSex()) && examApply.getSex().contains("女"))
                    .collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(femaleApplyList)) {
                for (ExamApplyDto examApply : femaleApplyList) {
                    ExamApplyItemDto examApplyItemDto = new ExamApplyItemDto();
                    examApplyItemDto.setApplyNo(examApply.getApplyNo());

                    List<ExamApplyItemDto> items = examApplyItemMapper.getList(examApplyItemDto);

                    Iterator<ExamApplyItemDto> it = items.iterator();
                    while (it.hasNext()) {
                        ExamApplyItemDto eai = it.next();
                        int itemStatus = Integer
                                .parseInt(StringUtils.isBlank(eai.getExamStatus()) ? "0" : eai.getExamStatus());
                        if (itemStatus == 0) {
                            itemStatus = Integer.parseInt(
                                    StringUtils.isBlank(eai.getScheduleStatus()) ? "0" : eai.getScheduleStatus());
                        }
                        if (itemStatus >= 40 || itemStatus == 4) {
                            it.remove();
                        } else {
                            if (itemStatus > 10) {
                                continue;
                            }
                            int amount = (eai.getAmount() != null) ? eai.getAmount() : 1;
                            int regAmount = (eai.getRegAmount() != null) ? eai.getRegAmount() : 0;
                            if (regAmount < amount) {
                                continue;
                            }
                            it.remove();
                        }
                    }
                    if (CollectionUtils.isEmpty(items)) {
                        continue;
                    }
                    commonServiceImpl.handItemCode(items, examApply.getExamSubClass());
                    examApply = configServiceImpl.noShowScheduleItem(examApply, items, dto.getTerminalType());
                    if (Objects.isNull(examApply)) {
                        continue;
                    }
                    List<ExamApplyItemDto> gestinfoDay = items.stream()
                            // 申请单的检查项目-是否有孕期限制
                            .filter(x -> StringUtils.isNotBlank(x.getGestinfoDayscope()))
                            .collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(gestinfoDay)) {
                        isGestational = "1";
                    }
                }
            }

            if ("1".equals(isGestational)) {
                QueryWrapper<ExamApply> examApplyQwForLastMensesDate = new QueryWrapper<>();
                ((examApplyQwForLastMensesDate.eq("SICK_ID", dto.getSickId()))
                        .isNotNull("LAST_MENSES_DATE"))
                        .orderByDesc("LAST_MENSES_DATE");

                ExamApply examApply = examApplyService.getOne(examApplyQwForLastMensesDate, false);
                if (Objects.isNull(examApply)) {
                    QueryWrapper<ExamApplyPatient> examApplyPatientQwForLastMensesDate = new QueryWrapper<>();
                    (examApplyPatientQwForLastMensesDate.eq("SICK_ID", dto.getSickId()))
                            .isNotNull("LAST_MENSES_DATE");
                    ExamApplyPatient examApplyPatient = examApplyPatientService
                            .getOne(examApplyPatientQwForLastMensesDate);
                    if (Objects.isNull(examApplyPatient)) {
                        QueryWrapper<ExamPatient> examPatientQw = new QueryWrapper<>();
                        (examPatientQw.eq("SICK_ID", dto.getSickId()))
                                .isNotNull("LAST_MENSES_DATE");
                        ExamPatient examPatient = examPatientService.getOne(examPatientQw);
                        if (Objects.isNull(examPatient)) {
                            isGestational = "1";
                        } else {
                            lastMensesDateStr = examPatient.getLastMensesDate();
                        }
                    } else {
                        lastMensesDateStr = examApplyPatient.getLastMensesDate();
                    }
                } else {
                    lastMensesDateStr = examApply.getLastMensesDate();
                }
            }
            if (StringUtils.isNotBlank(lastMensesDateStr)) {
                Date nowDate = DateUtil.getNow();
                Date lastMensesDate = DateUtil.parse(lastMensesDateStr, DateUtil.FORMAT_DATE);
                int allDays = (int) ((nowDate.getTime() - lastMensesDate.getTime()) / 86400000L);
                int weeks = allDays / 7;
                int days = allDays % 7;
                // 周数小于50 表明还在孕期
                if (weeks < 50) {
                    isGestational = "2";
                    resultMap.put("weeks", weeks);
                    resultMap.put("days", days);
                    resultMap.put("lastMensesDate", lastMensesDateStr);
                }
            }
            resultMap.put("isGestational", isGestational);
            resultList.add(resultMap);
        }
        return JsonResultUtil.success("成功", resultList);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult delSign(ExamApplyDto dto) {
        ExamApplyDto ea = commonServiceImpl.getApplyForScheduleItem(dto);
        ea = commonServiceImpl.getScheduleToExamApply(dto, ea);
        if ("40".equals(ea.getExamStatus()) && !DateUtil.getCurrDateStr().equals(ea.getScheduleDate())) {
            return JsonResultUtil.failure("该病人已经做过检查，无法取消报到！");
        }
        boolean bool = false;
        if (!ConstantsUtil.ScheduleStatus.ONE.getStatus().equals(ea.getScheduleStatus())) {
            String actType = ConstantsUtil.ActType.CANCEL.getType();
            if ("10".equals(ea.getExamStatus())) {
                actType = ConstantsUtil.ActType.CANCEL_SIGN.getType();
            }
            ea.setMergeNo(dto.getMergeNo());
            JsonResult recedeCostResult = commonServiceImpl.recedeCost(ea, actType, commonServiceImpl.dictUsers(dto));
            if (recedeCostResult != null && !"0".equals(recedeCostResult.getStatus())) {
                return JsonResultUtil.failure(recedeCostResult.getMessage());
            }
            ea.setTerminalType(dto.getTerminalType());
            JsonResult cancelSign = commonServiceImpl.cancelSign(ea);
            if (!"0".equals(cancelSign.getStatus())) {
                return JsonResultUtil.failure(cancelSign.getMessage());
            }
            if (!ea.getApplyNo().startsWith("RE")) {
                int count = 0;
                for (ExamApplyItemDto item : ea.getItems()) {
                    Map<String, Object> itemMap = new HashMap<String, Object>();
                    itemMap.put("APPLY_NO", item.getApplyNo());
                    itemMap.put("ITEM_NO", item.getItemNo());
                    UpdateWrapper<ExamApplyItem> update = new UpdateWrapper<>();
                    update.allEq(itemMap, false);
                    ExamApplyItem examApplyItem = new ExamApplyItem();
                    examApplyItem.setRegAmount(0);
                    if (item.getScheCancel() == null) {
                        examApplyItem.setScheCancel(0);
                    }
                    count += examApplyItemMapper.update(examApplyItem, update);
                }
                if (count < 1) {
                    return JsonResultUtil.failure("取消报到失败");
                }
            }
            boolean isExamClass4Organ = configServiceImpl.getOrganExamClassList().contains(ea.getExamClass());
            Double reqCount = 1.0;
            if (isExamClass4Organ) {
                reqCount = commonServiceImpl.getOrgansReqCount(ea);
                if (reqCount == null) {
                    reqCount = commonServiceImpl.getReqOrganByItems(ea.getItems());
                }
            }
            ExamApplyDto eaDto = new ExamApplyDto();
            eaDto.setOrgans(ea.getOrgans());
            eaDto.setApplyNo(dto.getApplyNo());
            eaDto.setScheduleDate(ea.getScheduleDate());
            eaDto.setScheduledId(ea.getScheduledId());
            eaDto.setNextApmRatio(ea.getNextApmRatio());
            eaDto.setMergeNo(dto.getMergeNo());
            eaDto.setReqCount(reqCount);
            eaDto.setApmCode(ea.getApmCode());
            eaDto.setRegularIdList(Arrays.asList(ea.getRegularId()));
            eaDto.setExamClass(ea.getExamClass());
            eaDto.setTerminalType(dto.getTerminalType());
            if (dto.getApplyNo().startsWith("RE")) {
                ExamScheduleItem scheduleItem = new ExamScheduleItem();
                scheduleItem.setExamStatus("");
                scheduleItem.setApplyNo(dto.getApplyNo());
                scheduleItem.setItemNo(dto.getItemNo());
                scheduleItem.setScheduledId(dto.getScheduledId());
                scheduleItemService.update(scheduleItem);
                bool = true;
            } else {
                bool = delExamSchedule(eaDto, isExamClass4Organ);
            }
            ea.setTerminalType(dto.getTerminalType());
            ea.setActType(actType);
            ea.setApplyNos(ea.getApplyNos());
            commonServiceImpl.addExamScheduleAct(ea, commonServiceImpl.dictUsers(dto));
        }
        if (!bool) {
            return JsonResultUtil.failure("取消报到失败");
        }
        ea.setType(ConstantsUtil.ActType.CANCEL_SIGN.getType());
        ea.setTerminalType(dto.getTerminalType());
        if (StringUtils.isNotBlank(ea.getExamStatus())) {
            ea.setScheduleStatus(ea.getExamStatus());
        }
        return JsonResultUtil.success("取消报到成功", ea);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult editExamApply(ExamApplyDto dto) {
        String applyNo = dto.getApplyNo();
        List<String> applyNos = new ArrayList<String>();
        String mergeNo = "";
        String itemNo = "";
        if (StringUtils.isNotBlank(dto.getMergeNo())) {
            applyNos = (List<String>) CommonUtil.mergeNo2ApplyNos(dto.getMergeNo());
            mergeNo = dto.getMergeNo().split(",")[0];
            int idx = mergeNo.lastIndexOf("-");
            applyNo = mergeNo.substring(0, idx);
            itemNo = mergeNo.substring(idx + 1, mergeNo.length());
        } else {
            applyNos.add(applyNo);
        }
        // ExamApplyDto eaDto = new ExamApplyDto();
        // eaDto.setApplyNo(applyNo);
        ExamApply examApplys = examApplyService.getExamApply(applyNo, null);
        ExamApplyDto examApply = new ExamApplyDto();
        if (StringUtils.isNotBlank(dto.getPhoneNumber())) {
            if (StringUtils.isNotBlank(dto.getSickId())) {
                examApply.setSickIds(CommonUtil.split2List(dto.getSickId()));
            }
        } else {
            examApply.setApplyNos(applyNos);
        }
        if (dto.getMemo() != null || dto.getPriorityOrder() != null) {
            ExamScheduleItemDto item = new ExamScheduleItemDto();
            item.setApplyNo(applyNo);
            item.setItemNo(Long.parseLong(itemNo));
            List<ExamScheduleItem> items = examScheduleItemServiceImpl.getItemList(item);
            if (items != null && items.size() > 0) {
                ExamScheduleDto es = new ExamScheduleDto();
                es.setScheduledId(items.get(0).getScheduledId());
                if (dto.getMemo() != null) {
                    es.setMemo(dto.getMemo());
                }
                if (dto.getPriorityOrder() != null) {
                    es.setQueueClass(dto.getPriorityOrder());
                }
                int j = examScheduleMapper.updateExamSchedule(es);
                if (j == 0) {
                    return JsonResultUtil.failure("优先级修改失败");
                }
            }
            if (dto.getPriorityOrder() != null) {
                examApply.setPriorityOrder(dto.getPriorityOrder());
                baseMapper.updateExamApply(examApply);
            }
        } else {
            examApply.setPhoneNumber(dto.getPhoneNumber());
            examApply.setAddress(dto.getAddress());
            examApply.setReqHospital(dto.getReqHospital());
            examApply.setExamSubClass(dto.getExamSubClass());
            examApply.setReqMemo(dto.getReqMemo());
            if (StringUtils.isNotBlank(dto.getTransTool())) {
                examApply.setTransTool(dto.getTransTool() + "|" + dto.getSendBack());
            }
            int i = baseMapper.updateExamApply(examApply);
            if (i == 0) {
                return JsonResultUtil.failure("修改失败");
            }
        }
        if (examApplys != null) {
            String description = "";
            if (StringUtils.isNotBlank(dto.getPhoneNumber())) {
                description = "病人ID：[" + dto.getSickId() + "] 修改联系号码： [" + examApplys.getPhoneNumber() + "] 为 ["
                        + dto.getPhoneNumber() + "]";
            } else if (StringUtils.isNotBlank(dto.getAddress())) {
                description = "合单号：[" + mergeNo + "] 修改联系地址： [" + examApplys.getMailingAddress() + "] 为 ["
                        + dto.getAddress() + "]";
            } else if (StringUtils.isNotBlank(dto.getPriorityOrder())) {
                description = "合单号：[" + mergeNo + "] 修改优先级： [" + examApplys.getPriorityOrder() + "] 为 ["
                        + dto.getPriorityOrder() + "] ";
            } else if (StringUtils.isNotBlank(dto.getExamSubClass())) {
                description = "合单号：[" + mergeNo + "] 修改检查子类： [" + examApplys.getExamSubClass() + "] 为 ["
                        + dto.getExamSubClass() + "]";
            } else if (StringUtils.isNotBlank(dto.getTransTool())) {
                description = "合单号：[" + mergeNo + "] 修改运送工具： [" + examApplys.getTransTool() + "] 为 ["
                        + dto.getTransTool() + "|" + dto.getSendBack() + "]";
            } else if (StringUtils.isNotBlank(dto.getReqHospital())) {
                description = "合单号：[" + mergeNo + "] 修改院区： [" + examApplys.getReqHospital() + "] 为 ["
                        + dto.getReqHospital() + "]";
            } else if (StringUtils.isNotBlank(dto.getMemo())) {
                description = "合单号：[" + mergeNo + "] 修改预约备注： [" + dto.getBeforeModifInfo() + "] 为 [" + dto.getMemo()
                        + "]";
            } else if (StringUtils.isNotBlank(dto.getReqMemo())) {
                description = "合单号：[" + mergeNo + "] 修改申请备注： [" + examApplys.getReqMemo() + "] 为 [" + dto.getReqMemo()
                        + "]";
            }
            String info = examApplys.getName() + "," + examApplys.getSex() + "," + examApplys.getAge() + ",ID:"
                    + examApplys.getSickId() + ",检查类别:" + examApplys.getExamClass() + ",申请单号:"
                    + examApplys.getApplyNo();
            description = info + "," + description;
            dto.setApplyNo(applyNo);
            dto.setHospitalCode(examApplys.getHospitalCode());
            dto.setActDescription(description);
            dto.setActType(ConstantsUtil.ActType.EDIT_APPLY.getType());
            DictUsersDto obj = commonServiceImpl.dictUsers(dto);
            commonServiceImpl.addExamScheduleAct(dto, obj);
        }
        return JsonResultUtil.success("成功");
    }

    @Override
    public JsonResult getScheduleExpireDate(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo())) {
            return JsonResultUtil.failure("applyNo不能为空");
        }
        if (StringUtils.isBlank(dto.getHospitalCode())) {
            return JsonResultUtil.failure("院区代码不能为空");
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        String scheduleDate = "";
        JsonResult jsonResult = scheduleSignService.getDateFirst(dto);
        if ("0".equals(jsonResult.getStatus())) {
            Map<String, String> map = (Map<String, String>) jsonResult.getResult();
            scheduleDate = map.get("scheduleDate");
            String scheduleApm = map.get("scheduleApm");
            resultMap.put("scheduleDate", scheduleDate);
            resultMap.put("scheduleApm", scheduleApm);
        }
        dto.setDate(StringUtils.isNotBlank(scheduleDate) ? scheduleDate : DateUtil.getCurrDateStr());
        JsonResult scheduleQueuesResult = getScheduleQueues(dto);
        ExamApplyDto examApplyDtoResult = (ExamApplyDto) scheduleQueuesResult.getResult();
        StringBuilder queueNameSb = new StringBuilder();
        if (examApplyDtoResult.getReserveQueue() != null && !examApplyDtoResult.getReserveQueue().isEmpty()) {
            for (Map<String, String> map2 : examApplyDtoResult.getReserveQueue()) {
                if (!map2.isEmpty()) {
                    queueNameSb.append("," + map2.get("queueName"));
                }
            }
        }
        DictExamQueueDto dictExamQueueDto = new DictExamQueueDto();
        if (StringUtils.isNotBlank(queueNameSb.toString())) {
            dictExamQueueDto.setQueueNameList(CommonUtil.strToList(queueNameSb.substring(1), ","));
        } else {
            dictExamQueueDto.setHospitalCode(dto.getHospitalCode());
            dictExamQueueDto.setApplyNo(dto.getApplyNo());
            dictExamQueueDto.setExamClass(dto.getExamClass());
        }
        dictExamQueueDto.setUseFlag("0");
        List<DictExamQueueDto> queues = dictExamQueueMapper.getQueueList(dictExamQueueDto);
        if (queues.size() == 0) {
            return JsonResultUtil.failure("当前申请单无可用的检查队列，如有疑问请到护士站咨询！");
        }
        boolean isBeginDay = false;
        LocalDate minBeginDate = LocalDate.now().plusYears(1L);
        LocalDate maxBeginDate = LocalDate.now();
        LocalDate maxEndDate = LocalDate.now();
        for (DictExamQueue queue : queues) {
            if (queue.getBeginDays() == null || queue.getBeginDays() == 0) {
                minBeginDate = LocalDate.now();
                isBeginDay = false;
                break;
            }
            LocalDate beginDate = LocalDate.now().plusDays(queue.getBeginDays());
            if (beginDate.isBefore(minBeginDate)) {
                minBeginDate = beginDate;
            }
            isBeginDay = true;
        }
        for (DictExamQueue queue : queues) {
            if (queue.getExpireDays() == null || queue.getExpireDays() == 0) {
                maxEndDate = null;
                break;
            }
            if (queue.getBeginDays() != null && queue.getBeginDays() > 0) {
                LocalDate beginDate = LocalDate.now().plusDays(queue.getBeginDays());
                if (beginDate.isAfter(maxBeginDate)) {
                    maxBeginDate = beginDate;
                }
            }
            LocalDate endDate = maxBeginDate.plusDays(queue.getExpireDays() - 1);
            if (!endDate.isAfter(maxEndDate)) {
                continue;
            }
            maxEndDate = endDate;
        }
        QueryWrapper<ExamApply> examApplyQw = new QueryWrapper<>();
        examApplyQw.eq("APPLY_NO", dto.getApplyNo());
        ExamApply examApply = examApplyService.getOne(examApplyQw, false);
        if (examApply.getSex().contains(ConstantsUtil.Gender.WOMAN.getValue())) {
            String lastMensesDateStr = commonServiceImpl.getLastMensesDate(examApply.getSickId());
            int minGestationalDays = 10000;
            int maxGestationalDays = 0;
            boolean isGestationalItem = false;
            QueryWrapper<ExamApplyItem> examApplyItemQw = new QueryWrapper<>();
            examApplyItemQw.eq("APPLY_NO", dto.getApplyNo());
            List<ExamApplyItem> examApplyItemList = examApplyItemMapper.selectList(examApplyItemQw);
            for (ExamApplyItem examApplyItem : examApplyItemList) {
                DictExamItemDto itemDto = new DictExamItemDto();
                itemDto.setExamClass(examApplyItem.getExamClass());
                itemDto.setItemCode(examApplyItem.getItemCode());
                itemDto.setNotNullDayscope("1");
                DictExamItem dictExamItem = dictExamItemService.getInfo(itemDto);
                if (dictExamItem != null) {
                    isGestationalItem = true;
                    if (StringUtils.isBlank(lastMensesDateStr)) {
                        return JsonResultUtil.failure("该申请单有孕周要求，请先填写末次月经");
                    }
                    String[] gestinfoDayscope = dictExamItem.getGestinfoDayscope().split("~");
                    int daysBegin = Integer.parseInt(gestinfoDayscope[0]);
                    int daysEnd = Integer.parseInt(gestinfoDayscope[1]);
                    if (daysBegin < minGestationalDays) {
                        minGestationalDays = daysBegin;
                    }
                    if (daysEnd <= maxGestationalDays) {
                        continue;
                    }
                    maxGestationalDays = daysEnd;
                }
            }
            if (isGestationalItem) {
                LocalDate lastMensesDate = LocalDate.parse(lastMensesDateStr,
                        DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                LocalDate beginDate2 = lastMensesDate.plusDays(minGestationalDays);
                LocalDate endDate2 = beginDate2.plusDays(maxGestationalDays);
                if (endDate2.isBefore(LocalDate.now())) {
                    return JsonResultUtil.failure("该检查受孕周限制，您已经错过最佳检查日期，如有疑问请到护士站咨询！");
                }
                if (maxEndDate != null) {
                    if (beginDate2.isAfter(maxEndDate) || endDate2.isBefore(maxBeginDate)) {
                        return JsonResultUtil.failure("由于受孕周限制，在队列开放预约时间内无适合您的检查日期，如有疑问请到护士站咨询！");
                    }
                    if (endDate2.isBefore(maxEndDate)) {
                        maxEndDate = endDate2;
                    }
                } else {
                    maxEndDate = endDate2;
                }
                if (beginDate2.isAfter(minBeginDate)) {
                    minBeginDate = beginDate2;
                }
            }
        }
        resultMap.put("startDate", minBeginDate);
        resultMap.put("expireDate", maxEndDate);
        if (maxEndDate != null) {
            resultMap.put("hint", "该检查预约只能预约到" + maxEndDate + "！");
        }
        return JsonResultUtil.success("成功", resultMap);
    }

    public ExamApplyDto getExamRefer(ExamApplyDto dto) {
        ExamApplyDto ea_ = new ExamApplyDto();
        ea_.setItemCode(dto.getItemCode());
        String applyNo = "RE";
        ea_.setApplyNo(applyNo);
        ea_.setReqDept(dto.getDeptCode());
        ea_.setHospitalCode(dto.getHospitalCode());
        // 获取执行科室和检查类别
        Map<String, Object> map = commonServiceImpl.getPerformDeptCodeAndExamClassAndItems(dto.getExamClass(),
                dto.getHospitalCode(), dto.getItemCode());
        if (map != null) {
            String examClass = map.get("examClass").toString();
            ea_.setExamClass(examClass);
            List<ExamApplyItemDto> items = (List<ExamApplyItemDto>) map.get("items");
            List<String> itemCodes = new ArrayList<String>();
            StringBuffer sb = new StringBuffer();
            for (ExamApplyItemDto examApplyItemDto : items) {
                itemCodes.add(examApplyItemDto.getItemCode());
                examApplyItemDto.setApplyNo(applyNo);
                sb.append("," + applyNo + "-" + examApplyItemDto.getItemNo());
            }
            Map<String, Object> mapGroup = new HashMap<String, Object>();
            mapGroup.put("examClass", examClass);
            mapGroup.put("itemCodes", itemCodes);
            mapGroup.put("patientSource", dto.getPatientSource());
            boolean isItemOrder = true;
            List<DictItemGroupDetailDto> digs = dictItemGroupMapper.getGroupForOrder(mapGroup);
            for (ExamApplyItemDto item : items) {
                for (DictItemGroupDetailDto dig : digs) {
                    if (item.getItemCode().equals(dig.getItemCode()) && dig.getScheduleOrder() != null) {
                        item.setScheduleOrderGroup(dig.getScheduleOrder());
                        isItemOrder = false;
                    }
                }
            }
            commonServiceImpl.collectionSort(items, isItemOrder);
            Map<String, Integer> dateMap = commonServiceImpl.getBeginDate(items);
            ea_.setBeginTime(Integer.valueOf(dateMap.get("beginTime")));
            ea_.setBeginDays(Integer.valueOf(dateMap.get("beginDays")));
            ea_.setItems(items);
            ea_.setMergeNo(sb.substring(1));
        } else {
            logger.error("通过检查类别和院区代码和项目获取内部检查类别和执行科室失败！参数：examClass:{},hospitalCode:{},itemCode:{}",
                    new Object[]{dto.getExamClass(), dto.getHospitalCode(), dto.getItemCode()});
        }
        return ea_;
    }

    @Override
    public JsonResult getScheduleQueues(ExamApplyDto dto) {
        ExamApplyDto ea = null;
        // itemcode 是虚单预约
        if (StringUtils.isNotBlank(dto.getItemCode())) {
            ea = getExamRefer(dto);
        } else {
            if (dto.getApplyNo().startsWith("RE")) {
                ea = examReferMapper.findByApplyNo(dto.getApplyNo());
            } else {
                Map<String, Object> map = new HashMap<>();
                map.put("applyNo", dto.getApplyNo());
                map.put("terminalType", dto.getTerminalType());
                ea = baseMapper.getExamApply(map);
            }
            ExamApplyItemDto examApplyItemDto = new ExamApplyItemDto();
            List<String> applyNos;
            if (StringUtils.isNotBlank(dto.getMergeNo())) {
                applyNos = CommonUtil.mergeNo2ApplyNos(dto.getMergeNo());
            } else {
                applyNos = CommonUtil.split2List(dto.getApplyNo());
            }
            examApplyItemDto.setApplyNos(applyNos);
            List<ExamApplyItemDto> items;
            if (ea.getApplyNo().startsWith("RE")) {
                items = examApplyItemMapper.getReItemList(examApplyItemDto);
            } else {
                items = examApplyItemMapper.getList(examApplyItemDto);
            }
            List<String> itemCodes = new ArrayList<String>();
            Map<String, Object> mapGroup = new HashMap<String, Object>();
            mapGroup.put("examClass", ea.getExamClass());
            mapGroup.put("itemCodes", itemCodes);
            mapGroup.put("patientSource", ea.getPatientSource());
            boolean isItemOrder = true;
            List<DictItemGroupDetailDto> digs = dictItemGroupMapper.getGroupForOrder(mapGroup);
            for (ExamApplyItemDto item : items) {
                itemCodes.add(item.getItemCode());
                for (DictItemGroupDetailDto dig : digs) {
                    if (item.getItemCode().equals(dig.getItemCode()) && dig.getScheduleOrder() != null) {
                        item.setScheduleOrderGroup(dig.getScheduleOrder());
                        isItemOrder = false;
                    }
                }
            }
            commonServiceImpl.collectionSort(items, isItemOrder);
            ea.setItems(items);
            Map<String, Integer> dateMap = commonServiceImpl.getBeginDate(items);
            ea.setBeginTime(Integer.valueOf(dateMap.get("beginTime")));
            ea.setBeginDays(Integer.valueOf(dateMap.get("beginDays")));
            int clamBeforesTime = configServiceImpl.getClamBeforesTime(ea.getExamClass(), applyNos);
            ea.setClamBeforesTime(clamBeforesTime);
            boolean isExamClass4Organ = configServiceImpl.getOrganExamClassList().contains(ea.getExamClass());
            double reqCount = 1.0;
            if (isExamClass4Organ) {
                reqCount = commonServiceImpl.getReqOrganByItems(items);
            }
            ea.setIsExamClass4Organ(isExamClass4Organ);
            ea.setReqCount(reqCount);
        }
        String terminalType = dto.getTerminalType();
        if (StringUtils.isBlank(terminalType)) {
            terminalType = "A";
        }
        ea.setTerminalType(terminalType);
        dto.setPerformDept(ea.getPerformDept());
        if (StringUtils.isNotBlank(ea.getExamClass())) {
            dto.setExamClass(ea.getExamClass());
        }
        List<DictExamQueueDto> lsQueue = commonServiceImpl.getQueueList(dto);
        List<Map<String, String>> reserveQueue = new ArrayList<>();
        List<Map<String, String>> noReserveQueue = new ArrayList<>();
        DictScheduleApmDto dictScheduleApmDto = new DictScheduleApmDto();
        dictScheduleApmDto.setScheduleDate(dto.getDate());
        dictScheduleApmDto.setWeekDate(DateUtil.getWeek(dto.getDate()));
        if (dto.getDate().compareTo(DateUtil.getCurrDateStr()) == 0) {
            dictScheduleApmDto.setCurrTime(DateUtil.getCurrentTime());
        }
        // List<DictExamQueue> noQueueList = new ArrayList<>();
        // List<String> noQueueStr = new ArrayList<>();
        for (DictExamQueueDto deq : lsQueue) {
            if (ea.getApplyNo().startsWith("RE") && !deq.getExamClass().equals(dto.getExamClass())) {
                continue;
            }
            if (ea.getBeginDays() > 0) {
                int expireDays = (deq.getExpireDays() == null) ? 0 : deq.getExpireDays();
                if (deq.getExpireDays() == null || ea.getBeginDays() < expireDays) {
                    deq.setExpireDays(ea.getBeginDays());
                }
            }
            Map<String, String> map = new HashMap<>();
            map.put("queueName", deq.getQueueName());
            map.put("queueAlias", StringUtils.isBlank(deq.getQueueAlias()) ? deq.getQueueName() : deq.getQueueAlias());
            List<DictExamQueueDto> queues = new ArrayList<>();
            queues.add(deq);
            List<DictExamQueueDto> list = commonServiceImpl.getQueueListByDate(queues, dto.getDate(), null);
            if (list == null || list.size() == 0) {
                noReserveQueue.add(map);
            } else {
                dictScheduleApmDto.setQueueName(deq.getQueueName());
                Map<String, DictScheduleApmDto> apmMap = commonServiceImpl.getScheduleApmMap(dictScheduleApmDto);
                boolean isNoQueue = false;
                for (String key : apmMap.keySet()) {
                    DictScheduleApmDto dsa = apmMap.get(key);
                    boolean bool = commonServiceImpl.isEnabledScheduleApm(dsa, ea, dto.getDate());
                    if (bool) {
                        bool = commonServiceImpl.quantityRuleJudge(ea, dsa, dto.getDate());
                        if (bool) {
                            isNoQueue = true;
                            reserveQueue.add(map);
                            break;
                        }
                    }
                }
                if (isNoQueue) {
                    continue;
                }
                noReserveQueue.add(map);
            }
        }
        ExamApplyDto examApplyDto = new ExamApplyDto();
        examApplyDto.setReserveQueue(reserveQueue);
        examApplyDto.setNoReserveQueue(noReserveQueue);
        examApplyDto.setExamClass(ea.getExamClass());
        return JsonResultUtil.success("成功", examApplyDto);
    }

    @Override
    public List<String> getSickIds(Map<String, String> map) {
        return baseMapper.getSickIds(map);
    }

    @Override
    public JsonResult getWaitExamInfo(ExamApplyDto dto) {
        Map<String, String> map = new HashMap<>();
        map.put("examNo", dto.getExamNo());
        map.put("result", "");
        map.put("desc", "");
        baseMapper.getWaitingInfo(map);
        String result = map.get("result");
        String desc = map.get("desc");
        if ("-1".equals(result) || StringUtils.isBlank(result)) {
            return JsonResultUtil.failure(desc);
        }
        ExamApplyDto applyDto = new ExamApplyDto();
        Map<String, String> m = CommonUtil.stringToMap(result);
        String queueName = m.get("queue_name");
        applyDto.setQueueName(StringUtils.isNotBlank(queueName) ? queueName : "");
        String queueNo = m.get("queue_no");
        applyDto.setQueueNo(StringUtils.isNotBlank(queueNo) ? queueNo : "");
        String currentQueueNo = m.get("current_queue_no");
        applyDto.setCurrentQueueNo(StringUtils.isNotBlank(currentQueueNo) ? currentQueueNo : "");
        String waitCount = m.get("waiting_cnt");
        applyDto.setWaitCount(StringUtils.isNotBlank(waitCount) ? waitCount : "");
        String jzCount = m.get("jz_waiting_cnt");
        applyDto.setJzCount(StringUtils.isNotBlank(jzCount) ? jzCount : "");
        String zhCount = m.get("zh_waiting_cnt");
        applyDto.setZhCount(StringUtils.isNotBlank(zhCount) ? zhCount : "");
        String waitTime = m.get("waiting_time");
        applyDto.setWaitTime(StringUtils.isNotBlank(waitTime) ? waitTime : "");
        String jzWaitTime = m.get("jz_waiting_cnt");
        applyDto.setJzWaitTime(StringUtils.isNotBlank(jzWaitTime) ? jzWaitTime : "");
        String zhWaiTime = m.get("zh_waiting_cnt");
        applyDto.setZhWaitTime(StringUtils.isNotBlank(zhWaiTime) ? zhWaiTime : "");
        String unsignCnt = m.get("unsign_cnt");
        return JsonResultUtil.success("成功", applyDto);
    }

    /**
     * 修改项目属性 是否需要镇静等标识
     *
     * @param dto
     * @return
     */
    @Override
    public JsonResult editApplyFlag(ExamApplyDto dto) {
        if (StringUtils.isBlank(dto.getApplyNo())) {
            return JsonResultUtil.failure("申请单号不能为空");
        }
        if (StringUtils.isBlank(dto.getType())) {
            return JsonResultUtil.failure("申请单标识类型不能为空");
        }
        if (StringUtils.isBlank(dto.getFlag())) {
            return JsonResultUtil.failure("申请单标识不能为空");
        }
        StringBuilder errMsgs = new StringBuilder();
        List<String> applyNoList = CommonUtil.split2List(dto.getApplyNo());
        for (String applyNo : applyNoList) {
            Map<String, Object> map = new HashMap<>();
            map.put("applyNo", applyNo);
            ExamApplyDto examApplyDto = baseMapper.getExamApply(map);
            if (examApplyDto != null) {
                String type = dto.getType();
                String flag = dto.getFlag();
                String flags = StringUtils.isNotBlank(examApplyDto.getFlags()) ? examApplyDto.getFlags() : "";
                int len = flags.length();
                flags += "00000000000000000000".substring(0, 20 - len);
                char[] flagArray = flags.toCharArray();
                flagArray[Integer.parseInt(type)] = flag.toCharArray()[0];
                flags = String.valueOf(flagArray);
                ExamApply examApply = new ExamApply();
                examApply.setFlags(flags);

                QueryWrapper<ExamApply> update = new QueryWrapper<>();
                update.eq("APPLY_NO", applyNo);
                int result = baseMapper.update(examApply, update);

                if (result <= 0) {
                    errMsgs.append("，" + applyNo);
                } else {
                    String mergeNo = applyNo + "-1";
                    String oldFlags = StringUtils.isNotBlank(examApplyDto.getFlags()) ? examApplyDto.getFlags() : "";
                    oldFlags += "00000000000000000000".substring(0, 20 - oldFlags.length());
                    char[] oldArr = oldFlags.toCharArray();
                    String oldFlag = "1".equals(String.valueOf(oldArr[Integer.parseInt(type)])) ? "是" : "否";
                    String newFlag = StringUtils.isBlank(flag) ? "否" : ("1".equals(flag) ? "是" : "否");
                    String description = "";
                    if (StringUtils.isNotBlank(dto.getType())) {
                        description = "合单号：[" + mergeNo + "] 修改(" + CommonUtil.applyFlag2Text(type) + ")： [" + oldFlag
                                + "] 为 [" + newFlag + "]";
                    }
                    String info = examApplyDto.getName() + "," + examApplyDto.getSex() + "," + examApplyDto.getAge()
                            + ",ID:" + examApplyDto.getSickId() + ",检查类别:" + examApplyDto.getExamClass() + ",申请单号:"
                            + examApplyDto.getApplyNo();
                    description = info + "," + description;
                    ExamApplyDto eaDto = new ExamApplyDto();
                    BeanUtils.copyProperties(examApplyDto, eaDto);
                    eaDto.setActDescription(description);
                    eaDto.setActType(ConstantsUtil.ActType.EDIT_APPLY.getType());
                    DictUsersDto obj = commonServiceImpl.dictUsers(dto);
                    commonServiceImpl.addExamScheduleAct(eaDto, obj);
                }
            } else {
                errMsgs.append("，" + applyNo);
            }
        }
        if (StringUtils.isNotBlank(errMsgs.toString())) {
            return JsonResultUtil.failure("[" + errMsgs.substring(1) + "]申请单修改失败");
        }
        return JsonResultUtil.success();
    }

    @Override
    public List<ExamApply> getList(ExamApplyDto dto) {
        QueryWrapper<ExamApply> qw = new QueryWrapper<>();
        //Map<String, String> map = new HashMap<String, String>();
        //qw.allEq(map, false);
        if (CollectionUtils.isNotEmpty(dto.getApplyNos())) {
            qw.in("APPLY_NO", dto.getApplyNos());
        }
        return baseMapper.selectList(qw);
    }

    /**
     * 获取检查项目提示
     *
     * @param dto
     * @return
     */
    public JsonResult getHint(ExamApplyDto dto) {
        ExamApplyDto ea = commonServiceImpl.getApplyForScheduleItem(dto);
        ea = commonServiceImpl.getScheduleToExamApply(dto, ea);

        if (StringUtils.isNotBlank(ea.getExamStatus())) {
            ea.setScheduleStatus(ea.getExamStatus());
        }
        ea.setTerminalType(dto.getTerminalType());

        Map<String, Object> scheduleLimitMap = configServiceImpl.scheduleLimit3(ea);
        if (scheduleLimitMap != null) {
            boolean isScheCancel = (scheduleLimitMap.get("isScheCancel") != null
                    && (Boolean) scheduleLimitMap.get("isScheCancel"));
            String scheCancelReminder = (scheduleLimitMap.get("scheCancelReminder") != null)
                    ? (String) scheduleLimitMap.get("scheCancelReminder")
                    : "";
            if (isScheCancel)
                return JsonResultUtil.failure(scheCancelReminder);
            if (StringUtils.isNotBlank(scheCancelReminder)) {
                return JsonResultUtil.success("2", scheCancelReminder, "");
            }
        }
        return JsonResultUtil.success();
    }

    /**
     * 获取患者事件段内预约的申请单列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<Object> getScheduledList(QueryScheduledApplyDto dto) {
        List<String> applyNoList = examScheduleMapper.querySickApplyNoList(dto);
        List<Object> result = new ArrayList<>();
        for (String item : applyNoList) {
            ExamApplyDto dto1 = new ExamApplyDto();
            dto1.setApplyNo(item);
            dto1.setTerminalType(ConstantsUtil.TerminalType.SELF.getType());
            JsonResult print = print(dto1);
            if ("0".equals(print.getStatus())) {
                result.add(print.getResult());
            }
        }
        return result;
    }

    @Override
    public List<String> getSickNoScheduleApplyNos(String sickId, List<String> examClasss) {
        return examScheduleMapper.getSickNoScheduleApplyNos(sickId, examClasss);
    }
}
